9.19题解
我大概在写一个月之前的题的题解?不用管我,我可能是疯了
T1
我现在也不太清楚我考场上为什么$WA$了,正解对题意的转化我觉得还挺神仙的,考虑一下每次都走$k$步会不会出现什么特殊的性质?废话,我问都问了,没有多尴尬事实上走$k$步这个性质,让我们想到真实情况是根本想不到把后面所有的黑白线,全部映射到$[0,k)$这个区间里,这样的话所有的黑段都密集的排列在了一起,我们只需要找到一个可以落脚的地方,那么当我们把他映射回去的时候,每次就都站在那一块地方就可以了,既然映射,你就${\%}k$呗,然后我们只需要判断两个连续的黑块之间有没有长度超过$s$可以落脚的地方,有就$TAK$,没有就$NIE$,映射的时候特殊处理一下映射之后落在区间开头和结尾的区间,算答案的时候计算一下最后一个黑块和终点之间的距离
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #define maxn 500500 5 #define ll long long 6 using namespace std; 7 struct node{ 8 int l,r; 9 }bla[maxn]; 10 int T,s,k,n,flag,js,ma,tp; 11 ll head; 12 int a[maxn]; 13 inline int read() 14 { 15 int e=0,f=1; char ch=getchar(); 16 while(ch<'0'||ch>'9') 17 { 18 if(ch=='-') f=-1; 19 ch=getchar(); 20 } 21 while(ch>='0'&&ch<='9') {e=(e<<3)+(e<<1)+(ch^48); ch=getchar();} 22 return e*f; 23 } 24 bool cmp(const node &a,const node &b) 25 { 26 return a.l==b.l?a.r<b.r:a.l<b.l; 27 } 28 int main() 29 { 30 //freopen("1.in","r",stdin); 31 //freopen("W.out","w",stdout); 32 T=read(); 33 while(T--) 34 { 35 s=read(); k=read(); n=read(); 36 head=0; flag=0; js=0; tp=0; 37 for(int i=1;i<=n;++i) 38 { 39 a[i]=read(); 40 if(i%2) 41 { 42 if(a[i]+s>k) tp=1; 43 int zuo=head%k,you=(head+1ll*a[i]-1)%k; 44 if(zuo>you) 45 { 46 bla[++js].l=zuo; bla[js].r=k-1; 47 bla[++js].l=0; bla[js].r=you; 48 } 49 else {bla[++js].l=zuo; bla[js].r=you;} 50 } 51 head+=1ll*a[i]; 52 } 53 if(tp) {printf("NIE\n"); continue;} 54 sort(bla+1,bla+js+1,cmp); 55 ma=bla[1].r; 56 for(int i=2;i<=js;++i) 57 { 58 if(bla[i].l-ma-1>=s) flag=1; 59 ma=max(ma,bla[i].r); 60 } 61 if(k-1-ma>=s) flag=1; 62 if(flag) printf("TAK\n"); 63 else printf("NIE\n"); 64 } 65 return 0; 66 }
T2
我觉得和雨天的尾巴几乎一毛一样,就是线段树合并,启发式合并也可以
1 #include<iostream> 2 #include<cstdio> 3 #define maxn 400400 4 #define L 1 5 #define R 500000 6 using namespace std; 7 struct node{ 8 int w,cs,zuo,you; 9 }a[maxn*50]; 10 int n,m,u,v,js; 11 int A[maxn],B[maxn]; 12 int head[maxn],to[maxn*2],xia[maxn*2]; 13 int fa[maxn],zs[maxn]; 14 int ans_mz[maxn],ans_rs[maxn]; 15 inline int read() 16 { 17 int e=0,f=1; char ch=getchar(); 18 while(ch<'0'||ch>'9') 19 { 20 if(ch=='-') f=-1; 21 ch=getchar(); 22 } 23 while(ch>='0'&&ch<='9') {e=(e<<3)+(e<<1)+(ch^48); ch=getchar();} 24 return e*f; 25 } 26 void add(int x,int y) 27 { 28 to[++js]=y; xia[js]=head[x]; head[x]=js; 29 } 30 void up(int fa) 31 { 32 if(a[a[fa].zuo].cs>a[a[fa].you].cs) {a[fa].cs=a[a[fa].zuo].cs; a[fa].w=a[a[fa].zuo].w;} 33 else if(a[a[fa].zuo].cs<a[a[fa].you].cs) {a[fa].cs=a[a[fa].you].cs; a[fa].w=a[a[fa].you].w;} 34 else {a[fa].cs=a[a[fa].zuo].cs; a[fa].w=min(a[a[fa].zuo].w,a[a[fa].you].w);} 35 } 36 int hb(int fa,int son,int l,int r) 37 { 38 if(fa==0||son==0) return fa+son; 39 if(l==r) {a[fa].cs+=a[son].cs; a[fa].w=l; return fa;} 40 int mid=(l+r)>>1; 41 a[fa].zuo=hb(a[fa].zuo,a[son].zuo,l,mid); a[fa].you=hb(a[fa].you,a[son].you,mid+1,r); 42 up(fa); return fa; 43 } 44 int ADD(int fa,int pos,int w,int l,int r) 45 { 46 if(!fa) fa=++js; 47 if(l==r) {a[fa].cs+=w; a[fa].w=pos; return fa;} 48 int mid=(l+r)>>1; 49 if(pos<=mid) a[fa].zuo=ADD(a[fa].zuo,pos,w,l,mid); 50 else a[fa].you=ADD(a[fa].you,pos,w,mid+1,r); 51 up(fa); return fa; 52 } 53 void dfs(int x) 54 { 55 int las=-1; 56 for(int i=head[x];i;i=xia[i]) 57 { 58 if(fa[to[i]]) continue; 59 fa[to[i]]=x; dfs(to[i]); las=to[i]; 60 } 61 if(las!=-1) 62 { 63 zs[x]=zs[las]; 64 for(int i=head[x];i;i=xia[i]) 65 { 66 if(fa[to[i]]!=x||to[i]==las) continue; 67 zs[x]=hb(zs[x],zs[to[i]],L,R); 68 } 69 } 70 zs[x]=ADD(zs[x],A[x],B[x],L,R); ans_mz[x]=a[zs[x]].w; ans_rs[x]=a[zs[x]].cs; 71 } 72 int main() 73 { 74 //freopen("2.in","r",stdin); 75 n=read(); m=read(); 76 for(int i=1;i<n;++i) {u=read(); v=read(); add(u,v); add(v,u);} 77 for(int i=1;i<=n;++i) {A[i]=read(); B[i]=read();} 78 js=0; fa[1]=-1; dfs(1); 79 for(int i=1;i<=n;++i) printf("%d %d\n",ans_mz[i],ans_rs[i]); 80 return 0; 81 }
T3
纪念一下我考后都没得分的题,这不咕能说的过去嘛