标签:col its eve man sizeof 一个队列 tac dfs nbsp
1001:Age of Moyu
在SPFA的时候开一个set或map记录一下转移到他的边的种类,转移的时候尽量选和当前这条边种类一样的边转移,玄学复杂度,记得fread读入挂和register进行常数优化。
1 #include<bits/stdc++.h> 2 3 #define maxn 100000+5 4 #define maxm 200000+5 5 6 using namespace std; 7 8 struct Edge{ 9 int u,v,c,nxt; 10 }e[maxm<<1]; 11 12 unordered_map <int,int> s[maxn]; 13 14 int head[maxn],dis[maxn],inq[maxn]; 15 int ind,n,m; 16 17 void addedge(int x,int y,int c){ 18 e[ind]=(Edge){x,y,c,head[x]},head[x]=ind++; 19 e[ind]=(Edge){y,x,c,head[y]},head[y]=ind++; 20 } 21 22 void spfa(){ 23 queue <int> q; 24 dis[1]=0; q.push(1); inq[1]=1; 25 s[1][0]=1; 26 while(!q.empty()){ 27 int x=q.front(); q.pop(); inq[x]=0; 28 for(int i=head[x];i!=-1;i=e[i].nxt){ 29 int flag=1; 30 if(s[x][e[i].c]) flag=0; 31 if(dis[e[i].v]>dis[x]+flag){ 32 dis[e[i].v]=dis[x]+flag; 33 s[e[i].v].clear(); 34 if(!s[e[i].v][e[i].c]) s[e[i].v][e[i].c]=1; 35 if(!inq[e[i].v]){ 36 inq[e[i].v]=1; 37 q.push(e[i].v); 38 } 39 } 40 else if(dis[e[i].v]==dis[x]+flag){ 41 if(!s[e[i].v][e[i].c]) { 42 s[e[i].v][e[i].c]=1; 43 if(!inq[e[i].v]){ 44 inq[e[i].v]=1; 45 q.push(e[i].v); 46 } 47 } 48 } 49 } 50 } 51 if(dis[n]!=0x3f3f3f3f) printf("%d\n",dis[n]); 52 else puts("-1"); 53 } 54 55 namespace fastIO { 56 #define BUF_SIZE 100000 57 bool IOerror = 0; 58 inline char nc() { 59 static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; 60 if(p1 == pend) { 61 p1 = buf; 62 pend = buf + fread(buf, 1, BUF_SIZE, stdin); 63 if(pend == p1) { 64 IOerror = 1; 65 return -1; 66 } 67 } 68 return *p1++; 69 } 70 inline bool blank(char ch) { 71 return ch == ‘ ‘ || ch == ‘\n‘ || ch == ‘\r‘ || ch == ‘\t‘; 72 } 73 inline int rd(int &x) { 74 char ch; 75 while(blank(ch = nc())); 76 if(IOerror) return -1; 77 for(x = ch - ‘0‘; (ch = nc()) >= ‘0‘ && ch <= ‘9‘; x = x * 10 + ch - ‘0‘); 78 return 1; 79 } 80 #undef BUF_SIZE 81 }; 82 using namespace fastIO; 83 84 int main(){ 85 freopen("x.in","r",stdin); 86 while(~rd(n)){ 87 rd(m); 88 ind=0; 89 for(register int i=1;i<=n;i++) inq[i]=0,dis[i]=0x3f3f3f3f,head[i]=-1; 90 for(register int i=1;i<=m;i++){ 91 int x,y,c; 92 rd(x); rd(y); rd(c); 93 addedge(x,y,c); 94 } 95 spfa(); 96 } 97 return 0; 98 }
1002:AraBellaC
枚举循环周期,对每个循环周期内的mxa,mnb,mxb,mnc二分寻找,要保证(mxa-1)%len<(mnb-1)%len和(mxb-1)%len<(mnc-1)%len。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <cmath> #include <vector> #include <iostream> #include <stack> #include <set> #include <map> using namespace std; const int MAX=1e5+5; int t,m; int a,b,c; vector<int> E[3]; void update(int aa,int bb,int cc){ int flag=0; if(aa<a) flag=1; else if(aa==a&&bb<b) flag=1; else if(aa==a&&bb==b&&cc<c) flag=1; if(flag) a=aa,b=bb,c=cc; } int main(){ int i,j; //freopen("data.in","r",stdin); scanf("%d",&t); while(t--){ int mx=0; a=b=c=0x3f3f3f3f; for(i=0;i<3;i++) E[i].clear(),E[i].push_back(0); scanf("%d",&m); for(i=0;i<m;i++){ int pos;char c; scanf("%d %c",&pos,&c); E[c-‘A‘].push_back(pos); mx=max(mx,pos); } for(i=0;i<3;i++) E[i].push_back(MAX),sort(E[i].begin(),E[i].end()); for(i=1;i<=mx;i++){ int mxa=0,mnc=MAX,mxb=0,mnb=MAX; for(j=(mx+i-1)/i;j>0;j--){ int tmp=*(upper_bound(E[0].begin(),E[0].end(),j*i)-1); if(tmp>(j-1)*i) mxa=max(mxa,(tmp-1)%i); tmp=*upper_bound(E[1].begin(),E[1].end(),(j-1)*i); if(tmp<=j*i) mnb=min(mnb,(tmp-1)%i); tmp=*(upper_bound(E[1].begin(),E[1].end(),j*i)-1); if(tmp>(j-1)*i) mxb=max(mxb,(tmp-1)%i); tmp=*upper_bound(E[2].begin(),E[2].end(),(j-1)*i); if(tmp<=j*i) mnc=min(mnc,(tmp-1)%i); if(mxa>=mnb||mxb>=mnc) break; } if(j==0) update(mxa+1,mxb-mxa,i-mxb-1); } if(a==0x3f3f3f3f) puts("NO"); else printf("%d %d %d\n",a,b,c); } return 0; }
1005:GuGuFishtion
首先推公式,欧拉函数是积性函数但不是一个完全积性函数,所以a,b不互质的情况下肯定还有一个偏移量。然后质因数分解一下a,b可以用数论知识证明差一个GCD(a,b)/Φ(GCD(a,b)),所以对于所有a,b不互质的情况下对答案的贡献是GCD(a,b)/Φ(GCD(a,b)),互质的话贡献是1。然后容斥,枚举k,容斥计算以k作为gcd的数对有多少个,然后乘上贡献就行了。
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1000000+5; LL tmp,ans; long long n,m,p; long long phi[N], cnt, prime[N/3],dy[N], val[N], q[N],sum_val[N],sum[N],inv[N],mu[N]; bool com[N]; int primes; void get_prime_phi(){ memset( com, false, sizeof( com ) ); primes = 0; phi[1] = 1; mu[1] = 1; for (int i = 2; i < N; ++i){ if (!com[i]) { prime[primes++] = i; phi[i] = i-1; mu[i] = -1; } for (int j = 0; j < primes && i*prime[j] <= N; ++j){ com[i*prime[j]] = true; if (i % prime[j]){ phi[i*prime[j]] = phi[i]*(prime[j]-1); mu[i*prime[j]] = -mu[i]; } else { mu[i*prime[j]] = 0; phi[i*prime[j]] = phi[i]*prime[j]; break; } } } } int lim; long long f[N],F[N]; void get(){ for(int i=1;i<=lim;++i) F[i]=1ll*(m/i)*(n/i)%p; for(int i=lim;i>0;--i){ f[i]=F[i]; for(int j=i+i;j<=lim;j+=i) f[i]-=1ll*f[j]%p; } for(int i=1;i<=lim;++i) f[i]%=p; } int main(){ //freopen("case.in","r",stdin); int T; scanf("%d",&T); get_prime_phi(); while(T--){ scanf("%lld%lld%lld",&n,&m,&p); tmp=ans=0; lim=min(n,m); memset(inv,0,sizeof(inv)); memset(f,0,sizeof(f)); inv[1]=1; for(register int i=2;i<=lim+2;i++) inv[i]=(LL)(p-p/i)*inv[p%i]%p; get(); for(register int i=1;i<=lim;i++){ val[i]=(LL)i*inv[phi[i]]%p; ans=(ans+(LL)val[i]*f[i]%p)%p; if(ans<0) ans+=p; //cout<<ans<<endl; } printf("%lld\n",ans); } return 0; }
1006:Lord Li‘s problem
有意思的dp;
根据异或的性质,X_0⊕X_1⊕X_2⊕X_3⊕…..⊕X_(M-1)=S⊕T
计算出S⊕T中一共有cnt个1,将这个二进制数标准化,使它成为前面N-cnt个0,后cnt个1的二进制数,答案保持不变,问题变为:用K个N位且有3个1的不同二进制数进行异或,最终得到前面N-cnt个0,后面cnt个1这个二进制数,有多少种方案?
递推。设d[K][M]表示用K个N位且有3个1的不同二进制数进行异或,最终得到前面N-cnt个0,后面cnt个1这个二进制数的方案数。
然后可以容易推出状态只可以从上一层的-1,-3,+1,+3这些状态转移过来
考虑加入重复串的影响,d[i][j]-= (d[i-2][j] * (C[n][3]-i+2);表示去除加入i-2个数字并且后面有j个1这个二进制数但后来又异或上两个之前没用过的相同的数的方案数,
考虑二进制数加入的先后顺序给答案带来的额外贡献,d[i][j]=d[i][j]*inv[i]%mod
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #include <string> #include <map> using namespace std; const long long mod=19260817; long long dp[30][50],c[50][50],inv[110]; char S[45],T[45]; int n,k; void init() { memset(dp,0,sizeof(dp)); } int main() { int i,j; c[0][0]=1; for(i=1;i<=45;i++) { c[i][0]=c[i][i]=1; for(j=1;j<i;j++) { c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; } } inv[1]=1; for(i=2;i<=60;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; int cas=1; while(scanf("%d%d",&n,&k)!=EOF) { if(n==0&&k==0) break; init(); scanf("%s%s",S,T); int num_1=0; for(i=0;i<n;i++) if((S[i]-‘0‘)^(T[i]-‘0‘)==1) num_1++; dp[0][0]=1; for(i=1;i<=k;i++) { for(j=0;j<=n;j++) { if(j>=3) dp[i][j]=(dp[i][j]+dp[i-1][j-3]*c[j][3])%mod; if(j>=1) dp[i][j]=(dp[i][j]+dp[i-1][j-1]*c[j][2]%mod*c[n-j][1])%mod; if(j+3<=n) dp[i][j]=(dp[i][j]+dp[i-1][j+3]*c[n-j][3])%mod; if(j+1<=n) dp[i][j]=(dp[i][j] + dp[i - 1][j + 1] * c[j][1] %mod* c[n - j][2]) % mod; if (i - 2 >= 0)dp[i][j] = (dp[i][j] - (dp[i - 2][j] * (c[n][3] - i + 2))) % mod; dp[i][j] = dp[i][j] * inv[i] % mod; if(dp[i][j]<0) dp[i][j]+=mod; } } printf("Case #%d: %lld\n",cas++, dp[k][num_1]); } return 0; }
1007:Reverse Game
1008:Traffic Network in Numazu
将环上的一个节点定为根节点,根节点连在的环上的一条边切开,得到一颗树,将树的权值按dfs序排列,用树状数组动态维护。若查询节点的lca不经过环,则直接为树上的距离,若经过环,可在两点在树上的距离以及绕环走的距离中取一个最小值作为答案,这些都可通过与LCA相关的计算得出,细节处理见代码。
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 6 #define maxn 100000+5 7 8 using namespace std; 9 10 struct Edge{ 11 int u,v,c,nxt; 12 }e[maxn<<1]; 13 14 int dfn[maxn<<1]; long long bit[maxn<<1]; 15 int data[maxn][3],fa[maxn][20],st[maxn],ed[maxn],head[maxn],flag[maxn],tag[maxn],du[maxn],dep[maxn]; 16 int n,q,ind,root,cut,leaf,pos; 17 18 void addedge(int x,int y,int z){ 19 e[ind]=(Edge){x,y,z,head[x]},head[x]=ind++; 20 e[ind]=(Edge){y,x,z,head[y]},head[y]=ind++; 21 } 22 23 int findroot(int x,int p){ 24 tag[x]++; 25 if(tag[x]==2){ 26 root=x; leaf=p; flag[x]=1; 27 return 1; 28 } 29 for(int i=head[x];i!=-1;i=e[i].nxt) 30 if(e[i].v!=p){ 31 int tmp=findroot(e[i].v,x); 32 if(tmp==1){ 33 cut=i; flag[x]=1; 34 return 2; 35 } 36 else if(tmp==2){ 37 flag[x]=1; 38 if(tag[x]==2) return 3; 39 return 2; 40 } 41 else if(tmp==3) return 3; 42 } 43 return 0; 44 } 45 46 void dfs(int x,int p){ 47 for(int i=head[x];i!=-1;i=e[i].nxt) 48 if(e[i].v!=p && i!=cut && i!=(cut^1)){ 49 fa[e[i].v][0]=x; dep[e[i].v]=dep[x]+1; 50 dfn[++pos]=e[i].c; st[e[i].v]=pos; 51 dfs(e[i].v,x); 52 dfn[++pos]=-e[i].c; ed[e[i].v]=pos; 53 } 54 } 55 56 void add(int x,int val){ 57 int N=maxn<<1; 58 while(x<N){ 59 bit[x]+=val; 60 x+=x&-x; 61 } 62 } 63 64 long long sum(int x){ 65 long long res=0; 66 while(x){ 67 res+=bit[x]; 68 x-=x&-x; 69 } 70 return res; 71 } 72 73 void init(){ 74 for(int i=1;i<20;i++) 75 for(int j=1;j<=n;j++) 76 fa[j][i]=fa[fa[j][i-1]][i-1]; 77 for(int i=1;i<=pos;i++) 78 add(i,dfn[i]); 79 80 } 81 82 int getlca(int x,int y){ 83 84 if(dep[x]>dep[y]) swap(x,y); 85 for(int i=19;i>=0;i--) if((dep[y]-dep[x])&(1<<i)) y=fa[y][i]; 86 if(x==y) return x; 87 for(int i=19;i>=0;i--) 88 if(fa[x][i]!=fa[y][i]){ 89 x=fa[x][i]; 90 y=fa[y][i]; 91 } 92 return fa[x][0]; 93 } 94 95 int main(){ 96 #ifndef ONLINE_JUDGE 97 freopen("x.in","r",stdin); 98 freopen("x.out","w",stdout); 99 #endif 100 int T; 101 scanf("%d",&T); 102 while(T--){ 103 scanf("%d%d",&n,&q); pos=ind=0; 104 for(int i=1;i<=n;i++){ 105 head[i]=-1; 106 tag[i]=du[i]=bit[i]=bit[i+n]=flag[i]=0; 107 for(int j=0;j<20;j++) fa[i][j]=0; 108 } 109 for(int i=1;i<=n;i++){ 110 int x,y,c; 111 scanf("%d%d%d",&x,&y,&c); 112 addedge(x,y,c); du[x]++; du[y]++; 113 data[i][0]=x; data[i][1]=y; data[i][2]=c; 114 } 115 bool fg=false; 116 for(int i=1;i<=n;i++) 117 if(du[i]==1){ fg=true; findroot(i,0); break; } 118 if(!fg) findroot(1,0); 119 dep[root]=1; st[root]=0; 120 dfs(root,0); 121 init(); 122 for(int i=1;i<=q;i++){ 123 int op,x,y; 124 scanf("%d%d%d",&op,&x,&y); 125 if(op==0){ 126 if(cut/2+1==x){ data[x][2]=y; continue; } 127 int a=data[x][0],b=data[x][1]; 128 if(dep[a]<dep[b]) swap(a,b); 129 add(st[a],-data[x][2]); add(ed[a],data[x][2]); 130 data[x][2]=y; 131 add(st[a],data[x][2]); add(ed[a],-data[x][2]); 132 } 133 else{ 134 int p=getlca(x,y); 135 long long ans=sum(st[x])+sum(st[y])-sum(st[p])*2; 136 if(flag[p]){ 137 int px=getlca(x,leaf),py=getlca(y,leaf); 138 if(dep[px]<dep[py]) swap(x,y),swap(px,py); 139 long long tmp=sum(st[x])+sum(st[leaf])-sum(st[px])*2+sum(st[y])+data[cut/2+1][2]; 140 printf("%lld\n",min(tmp,ans)); 141 } 142 else printf("%lld\n",ans); 143 } 144 } 145 } 146 return 0; 147 }
1009:Tree
将每个点向上跳能到达的节点标记为一个新的父节点,根据这个新的父节点能建出一颗新树,根节点表示为能跳到原树的外部,故答案即为某个点的深度。为了动态维护这颗树,可以考虑使用LCT维护,通知记录子树的大小,Access后子树大小即为所求点的深度。
1 #include<bits/stdc++.h> 2 3 #define maxn 100000+5 4 5 using namespace std; 6 7 struct Edge{ 8 int u,v,nxt; 9 }e[maxn<<1]; 10 11 struct Splay_Tree{ 12 int ch[2]; 13 int sz,flip,fa,pf; 14 void init(){ 15 ch[0]=ch[1]=sz=flip=fa=pf=0; 16 } 17 }tr[maxn<<1]; 18 19 int st[maxn],head[maxn],mf[maxn],dep[maxn],fa[maxn][20]; 20 int n,q,top,ind; 21 22 inline int in(){ 23 int x=0; char ch=getchar(); 24 for(;!isdigit(ch);ch=getchar()); 25 for(; isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; 26 return x; 27 } 28 29 inline void Pushdown(int k){ 30 if(tr[k].flip){ 31 tr[k].flip^=1; 32 tr[tr[k].ch[0]].flip^=1; 33 tr[tr[k].ch[1]].flip^=1; 34 swap(tr[k].ch[0],tr[k].ch[1]); 35 } 36 } 37 38 inline void Update(int k){ 39 tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+1; 40 } 41 42 void Rotate(int &k,int d){ 43 int t=tr[k].ch[d^1],Fa=tr[k].fa,Pf=tr[k].pf; 44 tr[k].pf=0; tr[k].fa=t; tr[tr[t].ch[d]].fa=k; 45 tr[t].pf=Pf; tr[t].fa=Fa; 46 tr[k].ch[d^1]=tr[t].ch[d]; tr[t].ch[d]=k; 47 Update(k); Update(t); k=t; 48 } 49 50 void Splay(int &k,int x){ 51 int d1=(tr[tr[k].ch[0]].sz<x?1:0),t=tr[k].ch[d1]; 52 if(d1==1) x-=tr[tr[k].ch[0]].sz+1; 53 if(x){ 54 int d2=(tr[tr[t].ch[0]].sz<x?1:0); 55 if(d2==1) x-=tr[tr[t].ch[0]].sz+1; 56 if(x){ 57 Splay(tr[t].ch[d2],x); 58 if(d1==d2) Rotate(k,d1^1); 59 else Rotate(tr[k].ch[d1],d1); 60 } 61 Rotate(k,d1^1); 62 } 63 } 64 65 int rankk(int k,int &rt){ 66 int res=tr[tr[k].ch[0]].sz+1; 67 st[++top]=k; rt=k; 68 while(tr[k].fa){ 69 int p=tr[k].fa; 70 st[++top]=p; 71 if(tr[p].ch[0]!=k) 72 res+=tr[tr[p].ch[0]].sz+1; 73 k=p; 74 } 75 rt=k; 76 return res; 77 } 78 79 inline void Haha(int k){ 80 int rt,x=rankk(k,rt); 81 while(top) Pushdown(st[top--]); 82 Splay(rt,x); 83 } 84 85 inline void Cutright(int k){ 86 if(tr[k].ch[1]){ 87 tr[tr[k].ch[1]].pf=k; 88 tr[tr[k].ch[1]].fa=0; 89 tr[k].ch[1]=0; 90 } 91 } 92 93 void Access(int k){ 94 Haha(k); Cutright(k); 95 while(tr[k].pf){ 96 int u=tr[k].pf; 97 Haha(u); Cutright(u); 98 tr[u].ch[1]=k; 99 tr[k].pf=0; tr[k].fa=u; 100 Update(u); k=u; 101 } 102 } 103 104 inline void Beroot(int k){ 105 Access(k); Haha(k); 106 tr[k].flip^=1; 107 } 108 109 inline void Cut(int k){ 110 Access(k); Haha(k); 111 int l=tr[k].ch[0]; 112 tr[k].ch[0]=0; 113 if(l){ 114 tr[l].fa=0; 115 tr[l].pf=0; 116 Update(k); 117 Haha(l); 118 } 119 } 120 121 inline void Link(int k,int p){ 122 Access(k); Beroot(p); 123 tr[p].pf=k; 124 } 125 126 void dfs(int x,int fa){ 127 for(int i=head[x];i!=-1;i=e[i].nxt) 128 if(e[i].v!=fa){ 129 dep[e[i].v]=dep[x]+1; 130 dfs(e[i].v,x); 131 } 132 133 } 134 135 void init(){ 136 for(int i=1;i<20;i++) 137 for(int j=1;j<=n;j++) 138 fa[j][i]=fa[fa[j][i-1]][i-1]; 139 } 140 141 int da(int x,int k){ 142 for(int i=19;i>=0;i--) if(k&(1<<i)) x=fa[x][i]; 143 return x; 144 } 145 146 void addedge(int x,int y){ 147 e[ind]=(Edge){x,y,head[x]},head[x]=ind++; 148 } 149 150 int main(){ 151 int T; 152 T=in(); 153 while(T--){ 154 n=in(); 155 memset(fa,0,sizeof(fa)); 156 for(int i=1;i<=n+1;i++) tr[i].init(); 157 ind=top=0; 158 tr[1].sz=tr[n+1].sz=1; tr[1].pf=n+1; 159 for(int i=1;i<=n;i++) head[i]=-1; 160 for(int i=2;i<=n;i++){ 161 int x=in(); fa[i][0]=x; 162 addedge(x,i); tr[i].sz=1; 163 } 164 for(int i=1;i<=n;i++) mf[i]=in(); 165 dfs(1,0); init(); 166 for(int i=1;i<=n;i++){ 167 if(mf[i]>dep[i]){ 168 tr[i].pf=n+1; 169 continue; 170 } 171 int p=da(i,mf[i]); 172 tr[i].pf=p; 173 } 174 q=in(); 175 for(int i=1;i<=q;i++){ 176 int op,x,y,newa; 177 op=in(); x=in(); 178 if(op==1){ 179 Beroot(n+1); 180 Access(x); Haha(x); 181 printf("%d\n",tr[tr[x].ch[0]].sz); 182 } 183 else{ 184 newa=in(); Cut(x); 185 if(newa>dep[x]) Link(n+1,x); 186 else{ 187 y=da(x,newa); 188 Link(y,x); 189 } 190 } 191 } 192 } 193 return 0; 194 }
1010:Sequence
矩阵快速幂,首先可以看出这题只能用矩阵快速幂,然后考虑对p进行分块,处理出p/i这个矩阵的指数,然后就矩阵快速幂了
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <cmath> #include <vector> #include <iostream> #include <stack> #include <set> #include <map> using namespace std; const int MAX=5; const int mod=1e9+7; struct Matrix{ long long mp[MAX][MAX]; //矩阵 int n,m; //行 列 Matrix(int _n,int _m){ n=_n,m=_m; for(int i=0;i<n;i++) for(int j=0;j<m;j++) mp[i][j]=0; } Matrix operator+(const Matrix &b)const{ Matrix tmp(n,m); for(int i=0;i<n;i++) for(int j=0;j<m;j++){ tmp.mp[i][j]=mp[i][j]+b.mp[i][j]; tmp.mp[i][j]%=mod; } return tmp; } Matrix operator*(const Matrix &b)const{ Matrix ret(n,b.m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) for(int k=0;k<m;k++){ ret.mp[i][j]+=mp[i][k]*b.mp[k][j]; ret.mp[i][j]%=mod; } return ret; } Matrix operator^(long long k)const{ Matrix ret(n,m),b(n,m); for(int i=0;i<n;i++){ for(int j=0;j<m;j++) b.mp[i][j]=mp[i][j]; ret.mp[i][i]=1; } while(k){ if(k&1) ret=ret*b; b=b*b; k>>=1; } return ret; } }; int t; int a,b,c,d,p,n; int main(){ int i; scanf("%d",&t); while(t--){ scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&p,&n); if(n==1) printf("%d\n",a); else if(n==2) printf("%d\n",b); else{ Matrix mc(3,1); mc.mp[0][0]=b; mc.mp[1][0]=a; mc.mp[2][0]=1; int now=3; Matrix mb(3,3); mb.mp[0][0]=d,mb.mp[0][1]=c,mb.mp[1][0]=1,mb.mp[2][2]=1; while(now<=n){ int tmp=p/now; mb.mp[0][2]=tmp; if(tmp==0){ mc=(mb^(n-now+1))*mc; break; } int x=p/tmp; if(x>n) x=n; mc=(mb^(x-now+1))*mc; now=x+1; } printf("%lld\n",mc.mp[0][0]); } } return 0; }
1011:Swordsman
瞎贪就行,按每个关键字开优先队列,直到从最后一个队列弹出表示可以击杀,同时加上exp就好。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <cmath> #include <vector> #include <iostream> #include <stack> #include <set> #include <map> using namespace std; struct FastIO { static const int S = 200; int wpos; char wbuf[S]; FastIO() :wpos(0) {} inline int xchar() { static char buf[S]; static int len = 0, pos = 0; if (pos == len) pos = 0, len = fread(buf, 1, S, stdin); if (pos == len) exit(0); return buf[pos++]; } inline int read() { int s = 1, c = xchar(), x = 0; while (c <= 32) c = xchar(); if (c == ‘-‘) s = -1, c = xchar(); for (; ‘0‘ <= c && c <= ‘9‘; c = xchar()) x = x * 10 + c - ‘0‘; return x * s; } ~FastIO() { if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0; } }io; const int MAX=1e5+5; int t,n,k,ans; struct node{ int x[10],y[10]; }mon[MAX]; int v[10]; struct cmpa{ bool operator()(node a,node b){ return a.x[0]>b.x[0]; } }; struct cmpb{ bool operator()(node a,node b){ return a.x[1]>b.x[1]; } }; struct cmpc{ bool operator()(node a,node b){ return a.x[2]>b.x[2]; } }; struct cmpd{ bool operator()(node a,node b){ return a.x[3]>b.x[3]; } }; struct cmpe{ bool operator()(node a,node b){ return a.x[4]>b.x[4]; } }; priority_queue<node,vector<node>,cmpa> a; priority_queue<node,vector<node>,cmpb> b; priority_queue<node,vector<node>,cmpc> c; priority_queue<node,vector<node>,cmpd> d; priority_queue<node,vector<node>,cmpe> e; int main(){ int i,j; //freopen("1.in","r",stdin); //freopen("10.out","w",stdout); t=io.read(); while(t--){ ans=0; while(!a.empty()) a.pop(); while(!b.empty()) b.pop(); while(!c.empty()) c.pop(); while(!d.empty()) d.pop(); while(!e.empty()) e.pop(); n=io.read(),k=io.read(); for(i=0;i<k;i++) v[i]=io.read(); for(i=0;i<n;i++){ for(j=0;j<k;j++) mon[i].x[j]=io.read(); for(j=0;j<k;j++) mon[i].y[j]=io.read(); a.push(mon[i]); } if(k==1){ while(!a.empty()){ node now=a.top(); if(v[0]>=now.x[0]){ ans++; a.pop(); v[0]+=now.y[0]; } else break; } } else if(k==2){ while(!a.empty()){ node now=a.top(); if(v[0]>=now.x[0]){ a.pop(); b.push(now); while(!b.empty()){ node now=b.top(); if(v[1]>=now.x[1]){ ans++; b.pop(); v[0]+=now.y[0]; v[1]+=now.y[1]; } else break; } } else break; } } else if(k==3){ while(!a.empty()){ node now=a.top(); if(v[0]>=now.x[0]){ a.pop(); b.push(now); while(!b.empty()){ node now=b.top(); if(v[1]>=now.x[1]){ b.pop(); c.push(now); while(!c.empty()){ node now=c.top(); if(v[2]>=now.x[2]){ ans++; c.pop(); v[0]+=now.y[0]; v[1]+=now.y[1]; v[2]+=now.y[2]; } else break; } } else break; } } else break; } } else if(k==4){ while(!a.empty()){ node now=a.top(); if(v[0]>=now.x[0]){ a.pop(); b.push(now); while(!b.empty()){ node now=b.top(); if(v[1]>=now.x[1]){ b.pop(); c.push(now); while(!c.empty()){ node now=c.top(); if(v[2]>=now.x[2]){ c.pop(); d.push(now); while(!d.empty()){ node now=d.top(); if(v[3]>=now.x[3]){ ans++; d.pop(); v[0]+=now.y[0]; v[1]+=now.y[1]; v[2]+=now.y[2]; v[3]+=now.y[3]; } else break; } } else break; } } else break; } } else break; } } else if(k==5){ while(!a.empty()){ node now=a.top(); if(v[0]>=now.x[0]){ a.pop(); b.push(now); while(!b.empty()){ node now=b.top(); if(v[1]>=now.x[1]){ b.pop(); c.push(now); while(!c.empty()){ node now=c.top(); if(v[2]>=now.x[2]){ c.pop(); d.push(now); while(!d.empty()){ node now=d.top(); if(v[3]>=now.x[3]){ d.pop(); e.push(now); while(!e.empty()){ node now=e.top(); if(v[4]>=now.x[4]){ ans++; e.pop(); v[0]+=now.y[0]; v[1]+=now.y[1]; v[2]+=now.y[2]; v[3]+=now.y[3]; v[4]+=now.y[4]; } else break; } } else break; } } else break; } } else break; } } else break; } } printf("%d\n",ans); for(i=0;i<k;i++) printf("%d%c",v[i],i==k-1?‘\n‘:‘ ‘); } return 0; }
2018 Multi-University Training Contest 7
标签:col its eve man sizeof 一个队列 tac dfs nbsp
原文地址:https://www.cnblogs.com/Hetui/p/9477405.html