\(T1\ \text{Scape}\)
meaning of the title
There are \ (n \) stores on a street, and the \ (I \) store provides \ (w_i \) units of food.
\(\ text{Scape} \) likes to eat, but the maximum capacity of \ (\ text{Scape} \) stomach is only \ (c \) units.
\(\ text{Scape} \) you can choose any point as the starting point to start walking (eating) to the right. Every time you pass a store (assuming the \ (I \) house), as long as there is residual capacity in his stomach, he will be unable to help eating \ (w_i \) units of food (if there is no residual capacity, he will not eat, but continue walking to the right).
\(\ text{Scape} \) to maximize the number of stores you have eaten, please find this number.
Data range: \ (n \le {10}^3,1\le c\le {10}^6 \)
thinking
It is found that there is no choice between eating and not eating. Consider greed and sweep through violence.
code
int n,c; int w[1005]; int ans,maxx; int main(){ n=read(),c=read(); for(int i=1;i<=n;i++){ w[i]=read(); } for(int i=1;i<=n;i++){ maxx=0; for(int j=i,k=c;j<=n&&k;j++){ if(k>=w[j]){ k-=w[j]; maxx++; } } ans=max(ans,maxx); } printf("%d\n",ans); return 0; }
\(T2\ \text{And}\)
meaning of the title
Give A table of \ (n \ times, n \), \ (x {I, J} \), \ (x {I, J} = A _i \ operatorname {and} A _j \), \ (A \) is an unknown sequence with A length of \ (n \).
Unfortunately, all the values of \ (x {I, I} \) are lost (so the read \ (x {I, I} \) has no meaning). You need to ask for A legal \ (A \).
Data range: \ (n\le {10}^3 \)
Tip: this question \ (\ operatorname{SPJ} \)
thinking
Because there is no inverse operation in and operation, it is considered to construct any combination method data. After binary splitting of each operation result, if there is a \ (1 \) in the \ (j \) digit related to the \ (i \) number and the operation result, the number must be \ (1 \) in the \ (j \) bit, and so on.
code
int n; int x[1005][1005]; int a[1005]; int main(){ n=read(); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ x[i][j]=read(); } } for(int k=0;k<=30;k++){ for(int i=1;i<=n;i++){ bool pd=0; for(int j=1;j<=n;j++){ int sit=x[i][j]&(1<<k); if(sit){ pd=1; } } if(pd){ a[i]|=(1<<k); } } } for(int i=1;i<=n;i++){ printf("%d ",a[i]); } printf("\n"); return 0; }
\(T3\ \text{Dist}\)
Problem surface
There is a \ (k \) fork tree with \ (n \) points. The number of points is \ (1\cdots n \), and its structure is described as follows:
- \Point (1 \) is the root node. If the minimum number of sides from a point to point \ (1 \) is \ (i \), it is called in the \ (i \) layer.
- The father of the \ (j \) point of the \ (I \) layer is the \ (\ lfloor(j-1)/k\rfloor+1 \) point of the \ (i-1 \) layer.
- The number of the \ (j \) point in the \ (i \) layer is \ (\ sum {P = 0} ^ {i-1} (k ^ P) + j \).
- From the third property, we can see that this is a complete \ (k \) fork tree.
\(q \) query times, and each time query the distance from point \ (x \) to point \ (y \) on the tree (the minimum number of sides passed).
thinking
One eye tree chain dissection (heavy fog).
You only need to skip ancestors. Here, all the numbers can be \ (- 1 \), so that during operation, the father number of the point with the number of \ (I \) is \ ((i-1)/k \) until it jumps to the common ancestor.
code
ll n,k,q; int main(){ n=read(),k=read(),q=read(); while(q--){ ll x=read()-1,y=read()-1; int cnt=0; while(x!=y){ if(x>y){ x=(x-1)/k; } else{ y=(y-1)/k; } cnt++; } printf("%d\n",cnt); } return 0; }
\(T4\ \text{Path}\)
Problem surface
There is a tree with \ (n \) points, and the edges of the number have weights. It is good to define a path if and only if the exclusive or sum of the weights of all edges on the path is equal to \ (0 \) ((the path from \ (u \) to \ (v \) and the path from \ (v \) to \ (u \) are regarded as the same path).
Now, to delete all edges in this tree in one order, please output the number of good paths of this tree before all deletion operations and the number of good paths after each deletion operation.
thinking
Positive order edge deletion is equivalent to directional edge deletion—— by APJ
It can be found that the XOR sum of any path can be obtained by maintaining the XOR sum to the root node.
Use \ (map \) as bucket maintenance.
code
int n; struct edge{ int to,nxt,w; }e[maxn]; struct node{ int from,to,w; }E[maxn]; int head[maxn],cnt; int xorsum[maxn]; inline void add_edge(int u,int v,int w){ e[++cnt].to=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } inline void dfs(int u,int fa){ for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(v==fa) continue; xorsum[v]=xorsum[u]^e[i].w; dfs(v,u); } } int del[maxn],fa[maxn]; map<int,int> mp[maxn]; inline int find(int x){ if(fa[x]==x) return fa[x]; return fa[x]=find(fa[x]); } ll ans[maxn],ansx; int main(){ n=read(); for(int i=1;i<n;i++){ int u=read(),v=read(),w=read(); add_edge(u,v,w); add_edge(v,u,w); E[i].from=u,E[i].to=v,E[i].w=w; } dfs(1,0); for(int i=1;i<n;i++){ del[i]=read(); } for(int i=1;i<=n;i++){ mp[i][xorsum[i]]=1; fa[i]=i; } for(int i=n-1;i>=0;i--){ int u=E[del[i]].from,v=E[del[i]].to,w=E[del[i]].w; u=find(u),v=find(v); if(mp[u].size()>mp[v].size()) swap(u,v); fa[u]=v; for(map<int,int>::iterator j=mp[u].begin();j!=mp[u].end();j++){ ansx+=(ll)(mp[v][j->first]*j->second); mp[v][j->first]+=j->second; } ans[i]=ansx; } for(int i=1;i<=n;i++){ printf("%lld\n",ans[i]); } return 0; }