Copy
/** @Author: wxyww* @Date: 2019-08-04 11:41:21* @Last Modified time: 2019-08-04 16:08:45*/#include<cstdio>#include<iostream>#include<cstdlib>#include<cmath>#include<ctime>#include<bitset>#include<cstring>#include<algorithm>#include<string>#include<queue>#include<vector>using namespace std;typedef long long ll;const int N = 200000 + 100;ll read() { ll 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 x*f;}int vis[N],tot;int n,K;vector<int>e[N * 10],ans[N];void print(int pos,int u) { if(u <= n) { ans[pos].push_back(u);vis = 1;return; } int k = e.size(); for(int i = 0;i < k;++i) { print(pos,e); }}int main() { int T = read(); while(T--) { n = read(),K = read(); tot = n; for(int i = 1;i <= n;++i) e[read()].push_back(i); for(int i = n;i > 1;--i) { int k = e.size(); while(k >= K) { ++tot; for(int j = 1;j <= K;++j,k--) { e[tot].push_back(e[k - 1]); } e[i - 1].push_back(tot); } } if(e[1].size() < K) { puts("0"); for(int i = 0;i <= tot;++i) e.clear(); for(int i = 0;i <= K;++i) ans.clear(); memset(vis,0,sizeof(vis)); continue; } puts("1"); for(int i = 0;i < K;++i) { int k = e[1]; print(i + 1,k); } for(int i = 1;i <= n;++i) if(!vis) ans[1].push_back(i); for(int i = 1;i <= K;++i) { int k = ans.size(); printf("%d ",k); for(int j = 0;j < k;++j) printf("%d ",ans[j]); puts(""); } for(int i = 0;i <= tot;++i) e.clear(); for(int i = 0;i <= K;++i) ans.clear(); memset(vis,0,sizeof(vis)); } return 0;}B#
对于已经给出的每一位,都根据给出的相等条件不断向前跳,将这个字符储存在第一个可知的位置。对于后面的询问,用同样的方法向前跳即可。
这样每个条件都只会最多跳一次。所以复杂度就是<span class="MathJax" id="MathJax-Element-13-Frame" tabindex="0" data-mathml="O(m)" role="presentation" style="display: inline; line-height: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; position: relative;">O(m)O(m)的。
Copy
/** @Author: wxyww* @Date: 2019-08-04 19:52:20* @Last Modified time: 2019-08-04 20:16:31*/#include<cstdio>#include<iostream>#include<cstdlib>#include<cmath>#include<ctime>#include<bitset>#include<cstring>#include<algorithm>#include<string>#include<queue>#include<vector>#include<map>using namespace std;typedef long long ll;const int N = 1000100;ll read() { ll 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 x*f;}int n,m1,m2,Q;struct node { int l1,r1,l2,r2;}a[N];pair<int,char> b[N];bool cmp(const node &A,const node &B) { return A.l2 < B.l2;}map<int,char>ans;int erfen(int x) { int ret = 0,l = 1,r = m2; while(l <= r) { int mid = (l + r) >> 1; if(x <= a[mid].r2) ret = mid,r = mid - 1; else l = mid + 1; } return ret;}int find(int x) { while(1) { int p = erfen(x); if(a[p].l2 > x || a[p].r2 < x) return x; int tmp = a[p].l2 - a[p].l1; x = x - (x - a[p].l2) / tmp * tmp; while(x >= a[p].l2) x -= tmp; }}int main() { n = read(),m1 = read(),m2 = read(),Q = read(); for(int i = 1;i <= m1;++i) { int x = read();char c; scanf("%c",&c); b = make_pair(x,c); } for(int i = 1;i <= m2;++i) { a.l1 = read();a.r1 = read();a.l2 = read();a.r2 = read(); } sort(a + 1,a + m2 + 1,cmp); for(int i = 1;i <= m1;++i) ans[find(b.first)] = b.second; while(Q--) { int x = find(read()); if(!ans.count(x)) puts("?"); else putchar(ans[x]),puts("");; } return 0;}C#
2.如果存在某个点的度数为偶数,肯定无解。考虑一个点肯定要作为恰好一条路径的端点,在这条路径中这个点被走了奇数次。而其他的每条路径这个点肯定都被走了偶数次。所以这个点的度数肯定为奇数。
Copy
//@Author: wxyww#include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<ctime>#include<cmath>#include<map>#include<string>using namespace std;typedef long long ll;const int N = 2000000 + 10;ll read() { ll 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 x * f;}int du[N];struct node { int u,v,nxt,id,id2;}e[N];struct NODE { int u,v,id1,id2;};queue<NODE>q;int head[N],ejs = 1;void add(int u,int v,int id,int id2) { e[++ejs].v = v;e[ejs].u = u;e[ejs].nxt = head;head = ejs;e[ejs].id = id;e[ejs].id2 = id2;}int viss[N],n,m,vis[N],dep[N];int dfs(int u,int fa) { int now = 0; vis = 1; for(int i = head;i;i = e.nxt) { if((i ^ 1) == fa) continue; int v = e.v; if(!vis[v]) { dep[v] = dep + 1; int k = dfs(v,i); if(!k) { viss[e.id] = 1;continue;} if(now) { q.push((NODE){e[k].v,e[now].v,e[k].id,e[now].id}); now = 0; } else now = k; } else { if(dep[v] < dep) continue; if(viss[e.id]) continue; if(now) { q.push((NODE){e.v,e[now].v,e.id,e[now].id}); now = 0; } else now = i; } viss[e.id] = 1; } if(now) { q.push((NODE){e[fa ^ 1].v,e[now].v,e[fa].id,e[now].id}); return 0; } return fa;}int vise[N],top,ans[N];void Eur(int u) { for(int &i = head;i;i = e.nxt) { if(vise[i >> 1]) continue; vise[i >> 1] = 1; int v = e.v; int tmp = i; Eur(v); ans[++top] = e[tmp].id2;ans[++top] = e[tmp].id; }}int main() { n = read(),m = read(); if(m & 1) return puts("0"),0; for(int i = 1;i <= m;++i) { int u = read(),v = read(); du++;du[v]++; add(u,v,i,0);add(v,u,i,0); } for(int i = 1;i <= n;++i) if(!(du & 1)) return puts("0"),0; puts("1"); dep[1] = 1; dfs(1,0); ejs = 1;memset(head,0,sizeof(head)); while(!q.empty()) { NODE k = q.front();q.pop(); add(k.u,k.v,k.id1,k.id2); add(k.v,k.u,k.id2,k.id1); } for(int i = 1;i <= n;++i) add(n + 1,i,-1,-1),add(i,n + 1,-1,-1); Eur(n + 1); for(int l = 1,r;l <= top;l = r + 1) { while(ans[l] == -1 && l <= top) ++l; if(l > top) break; r = l + 1; while(ans[r] != -1 && r <= top) ++r; printf("%d ",r - l); for(int i = l;i <= r - 1;++i) printf("%d ",ans); puts(""); } return 0;}总结#
注意细节。
认真读题,get到全部条件。
本文深入解析算法竞赛中的关键策略,包括理解题目、样例分析、数据结构应用及优化技巧,提供实战代码示例,帮助参赛者提升解题效率。
288

被折叠的 条评论
为什么被折叠?



