#include<bits/stdc++.h>#defineDCint T =gi<int>();while(T--)#definefifirst#definesesecond#definepbpush_back#definempmake_pair#defineAdd(a, b) a =(a + b)% mod#defineMul(a, b) a =1ll* a * b % mod#definechkmin(a, b) a =min(a, b)#definechkmax(a, b) a =max(a, b)#defineintlonglongusingnamespace std;typedeflonglong LL;typedefunsignedlonglong ULL;typedef pair <int,int> PII;typedef pair <LL,int> PLI;typedef pair <LL, LL> PLL;template<typenameT>inline T gi(){
T x =0, f =1;char c =getchar();while(c <'0'|| c >'9'){if(c =='-') f =-1; c =getchar();}while(c >='0'&& c <='9') x = x *10+ c -'0', c =getchar();return f * x;}constint N =200003, M = N <<1;int n, x, a[N];
map <int,int> p;inlinevoidsolve(){
n =gi<int>(), x =gi<int>();
p.clear();for(int i =1; i <= n; i+=1) a[i]=gi<int>(),++p[a[i]];for(auto&y : p)if(y.se){int now = y.fi * x;int mn =min(p[now], y.se);
y.se -= mn;
p[now]-= mn;}int sum =0;for(auto y : p) sum += y.se;
cout << sum << endl;return;}signedmain(){//freopen(".in", "r", stdin); freopen(".out", "w", stdout);
DC solve();return!!0;}
B
阴间构造
对于这种构造,我们肯定是要先找到一种基本操作,然后根据基本操作去构造方案。
不难发现无解的必要条件是存在数字出现了奇数次。下面我们通过构造方案证明其他情况下一定有解。
基本操作:翻转一段区间,即 abc→cba。
操作如下:
abcabcaa–––abcabb–––aabcabcc–––ba[abcabc]cba
从前往后扫描序列,将相邻两个相同字符的位置配对,假设其中一对是 (i,j)。
那么我们可以通过依次翻转 (i,j−1) 和 (i,j) 将 j 移动到 i 之后且其他字符相对顺序不变。
#include<bits/stdc++.h>#defineDCint T =gi<int>();while(T--)#definefifirst#definesesecond#definepbpush_back#definempmake_pair#defineAdd(a, b) a =(a + b)% mod#defineMul(a, b) a =1ll* a * b % mod#definechkmin(a, b) a =min(a, b)#definechkmax(a, b) a =max(a, b)usingnamespace std;typedeflonglong LL;typedefunsignedlonglong ULL;typedef pair <int,int> PII;typedef pair <LL,int> PLI;typedef pair <LL, LL> PLL;template<typenameT>inline T gi(){
T x =0, f =1;char c =getchar();while(c <'0'|| c >'9'){if(c =='-') f =-1; c =getchar();}while(c >='0'&& c <='9') x = x *10+ c -'0', c =getchar();return f * x;}constint INF =0x3f3f3f3f, N =503, M = N <<1;int n, now, a[N], c[N], cnt, p[N], t[N];
vector <int> b;int pp[N], pre[N];
vector <PII> ans;
vector <int> lens;bool vis[N];inlinevoidfilp(int l,int st,int len,int op){if(len <2)return;
now += len;if(!op)for(int i =1; i <= len; i+=1)
ans.pb({now++, c[a[st + i -1]]});else{for(int i = len -1; i >=1; i-=1)
ans.pb({now++, c[a[st + i -1]]});
ans.pb({now++, c[a[st + len -1]]});}
lens.pb(len <<1);}inlinevoidrebuild(){int qq =0;for(int i =1; i <= n; i+=1)if(vis[i]) t[++qq]= a[i];int tmp = qq;for(int i =1; i <= n; i+=1)if(!vis[i]) t[++qq]= a[i];for(int i =1; i <= n; i+=1) a[i]= t[i], pre[i]= pp[i]= vis[i]=0;for(int i =1; i <= tmp; i+=1) vis[i]=1;for(int i = tmp +1; i <= n; i+=1)if(!pre[a[i]]) pre[a[i]]= i;else pp[pre[a[i]]]= i, pre[a[i]]=0;}inlinevoidsolve(){
n =gi<int>();
b.clear(), ans.clear(), lens.clear();for(int i =1; i <= n; i+=1) pre[i]= p[i]= vis[i]=0;for(int i =1; i <= n; i+=1) a[i]= c[i]=gi<int>();sort(c +1, c +1+ n); cnt =unique(c +1, c +1+ n)- c -1;for(int i =1; i <= n; i+=1) a[i]=lower_bound(c +1, c +1+ cnt, a[i])- c,++p[a[i]];for(int i =1; i <= n; i+=1)if(p[i]&1)return(void)puts("-1");for(int i =1; i <= n; i+=1)if(!pre[a[i]]) pre[a[i]]= i;else pp[pre[a[i]]]= i, pre[a[i]]=0;
now =0;for(int i =1; i <= n; i+=2)filp(now, i, pp[i]- i,0),filp(now, i, pp[i]- i +1,1), lens.pb(2), now +=2, vis[i]= vis[pp[i]]=1,rebuild();
cout << ans.size()<< endl;for(auto x : ans) cout << x.fi <<' '<< x.se << endl;
cout << lens.size()<< endl;for(auto x : lens) cout << x <<' ';puts("");return;}intmain(){// freopen(".in", "r", stdin); freopen(".out", "w", stdout);
DC solve();return0;}
考虑并查集 + set 启发式合并,每次覆盖就把 [l−1,r] 的集合并起来,加入线段就直接在 r 所在的集合加入点 l,查询直接看在 x 所在集合有没有点在 [l1,x] 之间,l1 也可以并查集算。
注意 set 启发式合并的时候直接交换两个 set 即可。
#include<bits/stdc++.h>#defineDCint T =gi<int>();while(T--)#definefifirst#definesesecond#definepbpush_back#definempmake_pair#defineAdd(a, b) a =(a + b)% mod#defineMul(a, b) a =1ll* a * b % mod#definechkmin(a, b) a =min(a, b)#definechkmax(a, b) a =max(a, b)usingnamespace std;typedeflonglong LL;typedefunsignedlonglong ULL;typedef pair <int,int> PII;typedef pair <LL,int> PLI;typedef pair <LL, LL> PLL;template<typenameT>inline T gi(){
T x =0, f =1;char c =getchar();while(c <'0'|| c >'9'){if(c =='-') f =-1; c =getchar();}while(c >='0'&& c <='9') x = x *10+ c -'0', c =getchar();return f * x;}constint INF =0x3f3f3f3f, N =200003, M = N <<1;int n, q;int fa[N], L[N];
set <int> s[N];intgetf(int u){return fa[u]== u ? u : fa[u]=getf(fa[u]);}inlinevoidUnion(int x,int y){int fx =getf(x), fy =getf(y);if(fx != fy){
fa[fx]= fy;chkmin(L[fy], L[fx]);if(s[fx].size()> s[fy].size())swap(s[fx], s[fy]);for(auto p : s[fx]) s[fy].insert(p);set<int>().swap(s[fx]);}}intmain(){// freopen(".in", "r", stdin); freopen(".out", "w", stdout);
n =gi<int>(), q =gi<int>();iota(fa +1, fa +2+ n,1);iota(L +1, L +2+ n,1);while(q--){int op =gi<int>();if(!op){int l =gi<int>(), r =gi<int>(), ty =gi<int>();if(!ty)for(int i =getf(r); i >= l;)Union(i, i -1), i =getf(i);else s[getf(r)].insert(l);}else{int u =gi<int>();if(L[getf(u)]!= u)puts("NO");else{int fu = L[getf(u -1)], fv =getf(u);auto x = s[fv].lower_bound(fu +1);if(x != s[fv].end()&&(*x)<= u)puts("YES");elseputs("N/A");}}}return0;}
D
核心:两个序列 {a} 和 {b} 没有相同元素的判断方法:记一个计数器 cnt,对于每一个 b 的子集,如果它的元素个数是奇数,就将 cnt 加上它在 a 中的出现次数,否则就减去它在 a 中的出现次数。最后如果 cnt=1 说明 a 和 b 至少有一个元素相同,否则它们就没有相同元素。
有这个结论之后对每一个子集哈希,双指针求答案即可。
#include<bits/stdc++.h>#defineDCint T =gi<int>();while(T--)#definefifirst#definesesecond#definepbpush_back#definempmake_pair#defineAdd(a, b) a =(a + b)% mod#defineMul(a, b) a =1ll* a * b % mod#definechkmin(a, b) a =min(a, b)#definechkmax(a, b) a =max(a, b)usingnamespace std;typedeflonglong LL;typedefunsignedlonglong ULL;typedef pair <int,int> PII;typedef pair <LL,int> PLI;typedef pair <LL, LL> PLL;template<typenameT>inline T gi(){
T x =0, f =1;char c =getchar();while(c <'0'|| c >'9'){if(c =='-') f =-1; c =getchar();}while(c >='0'&& c <='9') x = x *10+ c -'0', c =getchar();return f * x;}constint INF =0x3f3f3f3f, N =100003, M = N <<1;const ULL base =11451419198101ull;
unordered_map <ULL,int> p;int n, m;structNode{int a[6], w;
ULL b[33];} a[N];inlinevoidmodify(int id,int op){for(int i =1; i <(1<< m); i+=1) p[a[id].b[i]]+= op;}inlineintquery(int id){int now =0;for(int i =1; i <(1<< m); i+=1)if(__builtin_parity(i)) now += p[a[id].b[i]];else now -= p[a[id].b[i]];return now;}intmain(){// freopen(".in", "r", stdin); freopen(".out", "w", stdout);
n =gi<int>(), m =gi<int>();for(int i =1; i <= n; i+=1){for(int j =0; j < m; j+=1)
a[i].a[j]=gi<int>();sort(a[i].a, a[i].a + m);for(int j =1; j <(1<< m); j+=1)for(int k =0; k < m; k+=1)if(j >> k &1)
a[i].b[j]= a[i].b[j]* base + a[i].a[k];
a[i].w =gi<int>();}sort(a +1, a +1+ n,[](Node x, Node y){return x.w < y.w;});for(int i =1; i <= n; i+=1)modify(i,1);int r = n, ans =2000000007;for(int l =1; l <= n; l+=1){bool fl =0;modify(l,-1);while(query(l)< r - l)modify(r--,-1), fl =1;if(fl)modify(++r,1),chkmin(ans, a[l].w + a[r].w);}if(ans !=2000000007)printf("%d\n", ans);elseputs("-1");return0;}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下