1,040
社区成员




这是我参加朝闻道知识分享大赛的第28篇文章.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define _cf() int _;cin>>_;while(_--)
const int N = 2e6;
const int inf = 2147483647;
void Solve()
{
int n;
cin>>n;
vector<ll> a(n);
vector<int> vis(n+1);
for(int i=1;i<n;i++) cin>>a[i];
ll res=(ll)n*(n+1)/2;
int op=0;// 超过的
for(int i=1;i<n;i++)
{
ll gap=a[i]-a[i-1];
if(gap>2*n-1){
cout<<"NO"<<endl;
return;
}
else if(gap>n) op+=gap;
else vis[gap]++;
}
if(a[n-1]<res){
int cnt=0,tmp=0;
for(int i=1;i<=n;i++){
if(vis[i]==0) cnt++,tmp+=i;
}
if(cnt==1&&tmp==res-a[n-1]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else if(a[n-1]==res){
if(op>0){
int tmp=0,cnt=0;
for(int i=1;i<=n;i++){
if(vis[i]>1){
cout<<"NO"<<endl;
return;
}
if(!vis[i]) tmp+=i,cnt++;
}
if(cnt==2&&tmp==op) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else{
int tmp1=0,cnt1=0;
int tmp2=0,cnt2=0;
for(int i=1;i<=n;i++){
if(!vis[i]) tmp1+=i,cnt1++; // 空位
if(vis[i]==2) tmp2+=i,cnt2++; // 重复
// printf("vis[%d]=%d\n",i,vis[i]);
}
if(cnt1==2&&cnt2==1&&tmp1==tmp2) cout<<"YES"<<endl;
// else printf("%d %d %d %d\n",cnt1,cnt2,tmp1,tmp2);
else cout<<"NO"<<endl;
}
}
else cout<<"NO"<<endl;
}
int main()
{
IOS;
int t;cin>>t;
while(t--) Solve();
}
典型的记忆化搜索
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define _cf() int _;cin>>_;while(_--)
const int N = 2e5+10;
const int inf = 2147483647;
vector<int> v[N];
ll a[N];
int vis[N];
ll dfs(int u)
{
if(vis[u]) return a[u];
ll res=0;
if(v[u].size()==0) res=a[u];
for(auto to:v[u]){
res+=dfs(to);
}
vis[u]=1;
return a[u]=min(a[u],res);
}
void Solve()
{
int n,k;
cin>>n>>k;
int x;
for(int i=1;i<=n;i++) cin>>a[i],v[i].clear(),vis[i]=0;
for(int i=1;i<=k;i++) cin>>x,a[x]=0,vis[x]=1;
for(int i=1;i<=n;i++)
{
int m;cin>>m;
while(m--){
cin>>x;
v[i].push_back(x);
}
}
// cout<<" -------- ";
for(int i=1;i<=n;i++) cout<<dfs(i)<<" ";
cout<<endl;
}
int main()
{
IOS;
_cf()
Solve();
}
看别人直接排序过的,我字典树调了好久,最后还是过了,虽然是看别人代码发现怎么错的(
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define _cf() int _;cin>>_;while(_--)
const int N = 2e5+10;
const int inf = 2147483647;
int ch[N*31][2],num[N*31],cnt[N*31];//字符串长度 31 乘上字符串个数 N ,避免RE
int idx;
//插入
void _insert(int x,int pos)
{
int p=0;
for(int i=31;i>=0;i--)
{
int b=(x>>i)&1;//将 x 从最高位依次取出一位
if(!ch[p][b]) ch[p][b]=++idx;//标记该节点
p=ch[p][b];//更新指向节点
cnt[p]++;
}
num[p]=pos;//最后记录储存的数
}
void del(int x)
{
int p=0;
for(int i=31;i>=0;i--)
{
int b=(x>>i)&1;//将 x 从最高位依次取出一位
p=ch[p][b];//更新指向节点
cnt[p]--;
}
}
//查询
int _find(int x)
{
int p=0;
for(int i=31;i>=0;i--)
{
int b=(x>>i)&1;
if(ch[p][b]&&cnt[ch[p][b]]>0) p=ch[p][b];
else p=ch[p][b^1];
}
return num[p];
}
int ck(int x)
{
int cnt=0;
while(x)
{
if(x&1) cnt++;
x>>=1;
}
return cnt;
}
void Solve()
{
int n,k;
cin>>n>>k;
vector<int> a(n+1);
for(int i=0;i<=n*30;i++) cnt[i]=ch[i][0]=ch[i][1]=num[i]=0;
idx=0;
for(int i=1;i<=n;i++) cin>>a[i],_insert(a[i],i);
int minn=inf,minx=inf;
int x,y;
for(int i=1;i<=n;i++)
{
del(a[i]);
int pos=_find(a[i]);
int op=a[pos]^a[i];
if(minx>op) minx=op,x=i,y=pos;
// cout<<pos<<" "<<i<<endl;
_insert(a[i],i);
}
// cout<<"---------- ";
int res=pow(2,k)-1;
res=res^(a[x]&a[y]);
cout<<x<<" "<<y<<" "<<res<<endl;
}
int main()
{
IOS;
_cf()
Solve();
}
还没补