noip近五年复习
一.noip2018
day 1
T1 铺设道路
13,18年通用入门题
#define ll long long int n,a[100006]; int main() { //freopen("in.txt","r",stdin); rd(n); int ans=0; inc(i,1,n) { rd(a[i]); if(a[i]>a[i-1])ans+=(a[i]-a[i-1]); } printf("%d",ans); re 0; }
当时我还写了好久,用了一种极其怪力的方法a了ta
T2 货币系统
完全背包嘛
int n,a[100],vis[30000]; int main() { //freopen("in.txt","r",stdin); int T; rd(T); while(T--) { rd(n); inc(i,1,n)rd(a[i]); memset(vis,0,sizeof vis); vis[0]=1; int ans=0; sort(a+1,a+n+1); inc(i,1,n) { if(!vis[a[i]])++ans; //vis[a[i]]=1; inc(j,a[i],a[n]) vis[j]|=vis[j-a[i]]; } printf("%d\n",ans); } re 0; }
想当年,我可是全凭这道题爆搜的70pts,压线2=
(说来惭愧……)
T3 塞道修建
这题思想还是较为简单,
二分一下答案,在判断能否
对于每个点将所有能配对的或自成一队的路径全部弄好
将剩下中最长的路径返回参与父节点选拔
就是stl用得伤心(因为要维护删除,所以迭代器随时要更新)
/* user liangsiyi. language: c++ */ #include<bits/stdc++.h> #define re return #define st static #define Min(a,b) (a)>(b)?(b):(a) #define Max(a,b) (a)>(b)?(a):(b) #define mem(a,x) memset(a,x,sizeof(a)) #define inc(i,l,r) for(register int i=l;i<=r;++i) #define dec(i,l,r) for(register int i=r;i>=l;--i) const int M=50000+5; using namespace std; int n,m,k,mid,flag=1,head[M],f[M],ff[M],s[M]; template <typename T>inline void read(T &x) { bool f=0;char c; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); x=f==1?-x:x; } template <typename T>void put(const T x) { if(x>9)put(x/10); putchar((x%10)|48); } template<typename T>inline void write(const T x) { if(x<0)putchar('-'),put(-x); else put(x); } struct node { int to,nt,v; }e[M<<1]; void add(int x,int y,int z) { e[++k].to=y;e[k].v=z;e[k].nt=head[x];head[x]=k; e[++k].to=x;e[k].v=z;e[k].nt=head[y];head[y]=k; } void dfs(int u,int fa) { f[u]=ff[u]=0; multiset<int>vi; for(int i=head[u];i;i=e[i].nt) { int v=e[i].to,w=e[i].v; if(v==fa)continue; dfs(v,u); //可能会重复dfs(同一v)但u不同 ,结果不同 f[u]+=f[v]; if(ff[v]+w>=mid)f[u]++; else vi.insert(ff[v]+w); } while(!vi.empty()) { multiset<int>::iterator i=vi.begin(); int x=*i;vi.erase(i); multiset<int>::iterator y=vi.lower_bound(mid-x); if(y==vi.end())ff[u]=x; else { f[u]++; vi.erase(y); } } } bool check() { dfs(1,0); if(f[1]>=m)re 1; re 0; } bool check1() { f[1]=0; int l=1; dec(i,l,n-1) if(s[i]>=mid)f[1]++; else { while(s[i]+s[l]<mid&&l<i)l++; if(s[i]+s[l]>=mid&&l<i)f[1]++,l++; else break; } if(f[1]>=m)re 1; re 0; } int main() { int x,y,z,l=1e6,r=0; read(n);read(m); inc(i,1,n-1){ read(x);read(y);read(z); add(x,y,z); l=Min(l,z);r+=z; if(x!=1)flag=0;s[i]=z; } sort(s+1,s+n); if(flag) { while(l<=r) { mid=(l+r)>>1; if(check1())l=mid+1; else r=mid-1; } } else while(l<=r) { mid=(l+r)>>1; if(check())l=mid+1; else r=mid-1; } printf("%d",l-1); re 0; }
day 2
T1 旅行
基环树拆点
发现基环树要么最大独立子集(强制枚举选与不选)
要么在环上区间dp
此题很显然,很暴力(毕竟是T1)
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=5005; int n,m,hd[maxn]; struct node{ int to,nt; }e[maxn<<1]; int k=1; inline void add(int x,int y){ e[++k]=(node){y,hd[x]};hd[x]=k; } namespace SOLU1{ inline void dfs(int x,int fa) { printf("%d ",x); priority_queue<int,vector<int>,greater<int> >q; for(int i=hd[x];i;i=e[i].nt){ int v=e[i].to; if(v!=fa)q.push(v); } while(!q.empty()) { int v=q.top();q.pop(); dfs(v,x); } } } namespace SOLU2{ int bridge[maxn<<1],ban[maxn<<1],dfn[maxn],low[maxn],tot; inline void tarjan(int x,int E) { dfn[x]=low[x]=++tot; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(i!=(E^1)) { if(!dfn[v]) { tarjan(v,i); if(low[v]>dfn[x])bridge[i]=bridge[i^1]=1; else low[x]=min(low[x],low[v]); } else low[x]=min(low[x],dfn[v]); } } } int a[maxn],b[maxn],tot_a,flag; inline bool dfs(int x,int fa) { a[++tot_a]=x; if(x>b[tot_a]&&(!flag))re 0; else if(x<b[tot_a])flag=1; priority_queue<int,vector<int>,greater<int> >q; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa||ban[i])continue; q.push(v); } while(!q.empty()) { int v=q.top();q.pop(); if(!dfs(v,x))re 0; } re 1; } inline void work() { inc(i,1,n)if(!dfn[i])tarjan(i,0); inc(i,1,n)b[i]=n+1; for(int i=2;i<=k;i+=2) if(!bridge[i]) { ban[i]=ban[i^1]=1; tot_a=0;flag=0; if(dfs(1,0)) { inc(i,1,n)b[i]=a[i]; } ban[i]=ban[i^1]=0; } inc(i,1,n) printf("%d ",b[i]); } } int main() { freopen("in.txt","r",stdin); int x,y; rd(n),rd(m); inc(i,1,m) { rd(x),rd(y); add(x,y); add(y,x); } if(m==n-1)SOLU1::dfs(1,0); else SOLU2::work(); re 0; }
T2 填数游戏
骗分过样例,打表出奇迹
这道题是真~打表找规律的好题
反正我今天只凹了65pts
剩下的只要是不会暴力,不过在考场上要真的不会,最好还是弄一下这种题
规律笔记比较好找
int main() { rd(n),rd(m); if(n>m)swap(n,m); if(n==1) { printf("%lld",Pow(2ll,m)); re 0; } if(n<=3&&m<=3) { if(n==2){ if(m==2)printf("12"); else if(m==3)printf("36"); } else printf("112"); re 0; } if(n==2) { int now=m-1; printf("%lld",Pow(3,now)*4%P); } else if(n==3) { int now=m-3; printf("%lld",Pow(3,now)*112%P); } else{ if(m == n)printf("%lld",(83*Pow(8,n)%P+5*Pow(2,n+7)%P)*190104168%P); else printf("%lld",(83*Pow(8,n)%P+Pow(2,n+8))*Pow(3,m-n-1)%P*570312504%P); } re 0; }
T3 保卫王国
ddp板子题
毒瘤吧,wc才讲就考到noip中来
只能暴力44pts(最大独立子集)
A:44:
const int maxn=2005; #define ll long long int n,m,p[maxn],hd[maxn]; ll f[maxn][2],inf=999999999999; struct node{ int to,nt; }e[maxn<<1]; int k; inline void add(int x,int y){ e[++k]=(node){y,hd[x]};hd[x]=k; } int limit[maxn]; inline void dfs(int x,int fa){ f[x][1]=p[x]; f[x][0]=0; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa)continue; dfs(v,x); f[x][0]+=f[v][1]; f[x][1]+=min(f[v][1],f[v][0]); } if(~limit[x])f[x][limit[x]]=inf; } int main() { freopen("in.txt","r",stdin); rd(n),rd(m); char GT[45]; memset(limit,-1,sizeof limit); scanf("%s",GT); inc(i,1,n)rd(p[i]); int x,y,a,b; inc(i,2,n) { rd(x),rd(y); add(x,y),add(y,x); } inc(i,1,m) { rd(x),rd(a),rd(y);rd(b); limit[x]=a^1; limit[y]=b^1; dfs(1,0); ll ans=min(f[1][0],f[1][1]); if(ans>=inf)puts("-1"); else printf("%lld\n",ans); limit[x]=-1; limit[y]=-1; } re 0; }
B:100
维护了一个直达链根的bot,树剖,寻常dp一下
在建线段树的时候以重儿子为转移矩阵核心(分为重儿子与其他儿子两类),
弄出一个关于矩阵的东西,加速和维护转移
ret.s[0][0]=min(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); ret.s[0][1]=min(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); ret.s[1][0]=min(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); ret.s[1][1]=min(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]);
大概就是这个东西
单点修改,再修改回来
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define int long long const int maxn=1e5+5; int n,m,hd[maxn],p[maxn]; struct node{ int to,nt; }e[maxn<<1]; int k; inline void add(int x,int y) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k; e[++k].to=x;e[k].nt=hd[y];hd[y]=k; } int siz[maxn],son[maxn],fa[maxn]; inline void dfs1(int x) { siz[x]=1; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to;if(v==fa[x])continue; fa[v]=x;dfs1(v); siz[x]+=siz[v]; if(siz[v]>siz[son[x]])son[x]=v; } } int tot,seg[maxn],rev[maxn],top[maxn],bot[maxn]; inline void dfs2(int x,int fp) { seg[x]=++tot;rev[tot]=x; top[x]=fp; if(son[x]) { dfs2(son[x],fp);bot[x]=bot[son[x]]; for(int i=hd[x];i;i=e[i].nt) if(!top[e[i].to])dfs2(e[i].to,e[i].to); } else bot[x]=x; } int f[maxn][2]; inline void dp(int x) { f[x][1]=p[x],f[x][0]=0; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(e[i].to==fa[x])continue; dp(v); f[x][1]+=min(f[v][0],f[v][1]); f[x][0]+=f[v][1]; } } //------------------------- struct Matrix{ int s[2][2]; inline Matrix operator*(Matrix a)const { Matrix ret; ret.s[0][0]=min(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); ret.s[0][1]=min(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); ret.s[1][0]=min(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); ret.s[1][1]=min(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]); re ret; } }t[maxn<<2],tmp[maxn],be[maxn]; const int inf=2147483647; #define ls rt<<1 #define rs rt<<1|1 inline void build(int rt,int l,int r) { if(l==r) { int x=rev[l]; int g1=f[x][1]-min(f[son[x]][0],f[son[x]][1]),g0=f[x][0]-f[son[x]][1]; be[l]=tmp[l]=t[rt]=(Matrix){g1,g1,g0,inf}; re ; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); t[rt]=t[ls]*t[rs]; } inline Matrix query(int rt,int l,int r,int x,int y) { if(x<=l&&r<=y) re t[rt]; int mid=(l+r)>>1; if(y<=mid)re query(ls,l,mid,x,y); else if(x>mid) re query(rs,mid+1,r,x,y); re query(ls,l,mid,x,y)*query(rs,mid+1,r,x,y); } inline void Modify(int rt,int l,int r,int pos) { if(l==r) { t[rt]=tmp[l]; re ; } int mid=(l+r)>>1; if(pos<=mid)Modify(ls,l,mid,pos); else Modify(rs,mid+1,r,pos); t[rt]=t[ls]*t[rs]; } inline Matrix Get_mat(int x){re query(1,1,n,seg[top[x]],seg[bot[x]]);} inline void modify(int x,int y) { if(y)tmp[seg[x]].s[0][0]=tmp[seg[x]].s[0][1]=inf; else tmp[seg[x]].s[1][0]=inf; while(x) { Matrix a=Get_mat(x);Modify(1,1,n,seg[x]); Matrix b=Get_mat(x); x=fa[top[x]]; if(!x)re ; tmp[seg[x]].s[0][1]=(tmp[seg[x]].s[0][0]+=min(b.s[1][0],b.s[0][0])-min(a.s[1][0],a.s[0][0])); tmp[seg[x]].s[1][0]+=b.s[0][0]-a.s[0][0]; } } inline void rebuild(int x) { while(x) { tmp[seg[x]]=be[seg[x]]; Modify(1,1,n,seg[x]); x=fa[top[x]]; } } #undef int int main() { #define int long long // freopen("in.txt","r",stdin); int x,y; char TY[4]; rd(n),rd(m); scanf("%s",TY); inc(i,1,n)rd(p[i]); inc(i,2,n) { rd(x),rd(y); add(x,y); } dfs1(1);dfs2(1,1);dp(1);build(1,1,n); int a,b; inc(i,1,m) { rd(a),rd(x),rd(b),rd(y); x^=1;y^=1; if(x&&y&&(fa[a]==b||fa[b]==a))puts("-1"); else { modify(a,x);modify(b,y); Matrix ans=Get_mat(1); int now=min(ans.s[1][0],ans.s[0][0]); printf("%lld\n",now); rebuild(a);rebuild(b); } } re 0; }
简而言之,就是通过树链剖分弄成线段树,使用矩阵(及区间可加性)加速
二.noip2017
day 1
T1 小凯的诱惑
这打表,这规律找得
我有50%是找不到这规律的
#include<bits/stdc++.h> using namespace std; int main() { long long a,b; scanf("%lld%lld",&a,&b); printf("%lld",a*b-(a+b)); return 0; }
T2 时间复杂度
蓝题的模拟 可见这题有多恶心了
#include<bits/stdc++.h> #define re return #define st static #define mem(a,b) memset((a),(b),sizeof(a)) #define Min(a,b) (a)<(b)?(a):(b) #define MAx(a,b) (a)>(b)?(a):(b) #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) using namespace std; int z,n,t,w,vis[100],ins[100]; string code[105],o; char c[105]; int gm(int i) { if(code[i][z+1]=='n'){ ++z;re 100000; } int vv=0; while('0'<=code[i][z+1]&&code[i][z+1]<='9')vv=vv*10+(code[i][++z]-48); re vv; } int check() { stack<int>s; int flag=0,x,y,k,jj=0,jc=0,ans=0,cnt=0; for(int i=1;i<=n;++i) { if(c[i]=='F') { k=code[i][1]-'a'+1; if(vis[k])re -1; vis[k]=1; s.push(k); if(!flag) { z=2;x=gm(i); z++;y=gm(i); if(x>y)flag=k; else if(y-x>1000) ins[k]=1,ans=max(ans,++cnt); } } else { if(s.empty())re -1; k=s.top();s.pop(); vis[k]=0; if(flag==k)flag=0; else if(ins[k])cnt--,ins[k]=0; } } if(!s.empty())re -1; re ans; } int go(int x) { int vv=0; while('0'<=o[x]&&o[x]<='9')vv=vv*10+(o[x++]-48); re vv; } int main() { // freopen("in.txt","r",stdin); scanf("%d",&t); while(t--) { mem(vis,0); mem(ins,0); mem(c,0); int f=0; scanf("%d",&n); while(c[0]!='O')c[0]=getchar(); getline(cin,o); if(o[1]=='n')f=1,w=go(3); else w=0; inc(j,1,n) { while(c[j]!=70&&c[j]!=69)c[j]=getchar(); getline(cin,code[j]); /* inc(i,0,code[j].size()) cout<<i<<" "<<code[j][i]<<endl;*/ } int ww=check(); if(ww==-1)printf("ERR\n"); else if(ww==w)printf("Yes\n"); else printf("No\n"); } return 0; }
T3 逛公园
day 2
T1 奶酪
只有一千个点,那就n^2的暴力+并查集判联通呗,
#include<bits/stdc++.h> using namespace std; long long t,n,h,r,u1,o1,r2; struct node { long long x,y,z; }hollow[1505]; int fa[1505]; int find(long long x) { if(fa[x]==x)return x; fa[x]=find(fa[x]); return fa[x]; } bool judge(long long i,long long j) { long long xx=abs(hollow[i].x-hollow[j].x), yy=abs(hollow[i].y-hollow[j].y), zz=abs(hollow[i].z-hollow[j].z); if(xx>r2||yy>r2||zz>r2)return 0; if(xx*xx+yy*yy+zz*zz>r2*r2)return 0; return 1; } int under[1001],over[1001]; int main() { //freopen("pp.txt","r",stdin); //freopen("op.txt","w",stdout); scanf("%ld",&t); while(t>0) { memset(under,0,sizeof(under)); memset(over,0,sizeof(over)); scanf("%lld%lld%lld",&n,&h,&r); long long f=0; u1=o1=0;r2=2*r;t--; for(long long i=1;i<=n;i++) { scanf("%lld%lld%lld",&hollow[i].x,&hollow[i].y,&hollow[i].z); if(hollow[i].z<=r)under[++u1]=i; if(h-hollow[i].z<=r)over[++o1]=i; } for(long long i=1;i<=n;i++) fa[i]=i; for(long long i=1;i<=n;i++) for(long long j=i+1;j<=n;j++) { if(!judge(i,j))continue; fa[find(i)]=find(j); } for(long long i=1;i<=u1;i++) { for(int j=1;j<=o1;j++) if(find(under[i])==find(over[j])) { f=1; break; } if(f==1)break; } if(f==0)printf("No\n"); else printf("Yes\n"); } return 0; }
T2 宝藏
仿佛记得机房某大佬有言:宝藏这个题本身就是一个宝藏
因为其极其n<=12的特征
所以理所当然不是暴力就是状压
dfs|随机化|状压都是ok的
然而我什么都不会……
70pts的dfs
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48) ; if(f)x=-x; } int n,m,d[20][20],dis[20]; int inf=555555555,ans=inf; inline void dfs(int dep,int sum) { if(sum>ans)re ; if(dep==n+1){ if(ans==51&&sum<ans) ans=sum; ans=sum; re ; } inc(i,1,n) if(dis[i]) { inc(j,1,n) if(!dis[j]&&d[i][j]!=inf) { dis[j]=dis[i]+1; dfs(dep+1,sum+dis[i]*d[i][j]); dis[j]=0; } } } int main() { freopen("a.in","r",stdin); int x,y,z; rd(n),rd(m); inc(i,1,n)inc(j,1,n)d[i][j]=inf; inc(i,1,n)d[i][i]=0; inc(i,1,m) { rd(x),rd(y),rd(z); d[x][y]=d[y][x]=min(d[y][x],z); } /* inc(k,1,n)inc(i,1,n)inc(j,1,n) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);*/ inc(i,1,n) { dis[i]=1; dfs(2,0); dis[i]=0; } printf("%d",ans) ; re 0; }
T3 队列
正解树状数组不会
写过又臭又长的splay
当然最好还是权值线段树
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long const int maxn=3e5+5; ll n,m,Q; ll T[maxn],ls[maxn<<5],rs[maxn<<5],num[maxn<<5]; ll use[maxn<<5]; ll tot,ans,flag; inline void query(ll &rt,ll l,ll r,ll x) { if(!rt) rt=++tot; ++use[rt]; if(l==r) { if(num[rt])ans=num[rt]; else if(!flag)ans=m*l; else ans=(flag-1)*m+l; re ; } int mid=(l+r)>>1; int cnt=mid-l+1-use[ls[rt]]; if(cnt>=x)query(ls[rt],l,mid,x); else query(rs[rt],mid+1,r,x-cnt); } inline void insert(ll &rt,ll l,ll r,ll pos) { if(!rt)rt=++tot; if(l==r) { num[rt]=ans; re ; } ll mid=(l+r)>>1; if(pos<=mid)insert(ls[rt],l,mid,pos); else insert(rs[rt],mid+1,r,pos); } ll sum[maxn]; int main() { freopen("b.in","r",stdin); ll x,y; rd(n),rd(m),rd(Q); inc(i,1,Q) { rd(x),rd(y); if(y==m) { flag=0; query(T[n+1],1,n+Q,x); printf("%lld\n",ans); ++sum[n+1]; insert(T[n+1],1,n+Q,sum[n+1]+n); } else { flag=x; query(T[x],1,m+Q,y); printf("%lld\n",ans); ++sum[n+1]; insert(T[n+1],1,n+Q,sum[n+1]+n); flag=0; query(T[n+1],1,n+Q,x); ++sum[x]; insert(T[x],1,m+Q,sum[x]+m-1); } } re 0; }
三.noip2016
day 1
T1 玩具谜题
zz模拟
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define dec(i,l,r) for(int i=l;i>=r;--i) int n,m,f[100005]; string s[100005]; int main() { freopen("b.in","r",stdin); rd(n),rd(m); inc(i,1,n) { rd(f[i]); cin>>s[i]; } int now=1,x,y; inc(i,1,m) { rd(x),rd(y); if(!x)//左数 { if(f[now]) { now+=y; if(now>n)now-=n; } else { now-=y; if(now<=0)now+=n; } } else { if(f[now]) { now-=y; if(now<=0)now+=n; } else{ now+=y; if(now>n)now-=n; } } } cout<<s[now]; re 0; }
T2 天天爱跑步
全场最难的题竟然放到了day1t2
有毒
估计也就只能骗部分分了
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=300005,maxz=600000,maxl=300000; int n,m,k,hd[maxn],ans[maxn],val[maxn]; struct node { int to,nt; }e[maxn<<1]; inline void add(int x,int y) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k; e[++k].to=x;e[k].nt=hd[y];hd[y]=k; } struct solu{ //分为s,t两部分 int top,tot,cnt; int rt[maxn*30],sum[maxn*30][2],ls[maxn*30],rs[maxn*30],first[maxn]; int rab[maxn*30]; struct ll{ int flag,op,val,nt; }st[maxn<<2]; inline void insert(int x,int y,int z,int f) { st[++top]=(ll){f,z,y,first[x]}; first[x]=top; } inline int New() { int now; if(tot)now=rab[tot--]; else now=++cnt; ls[now]=rs[now]=sum[now][0]=sum[now][1]=0; re now; } inline void Throw(int x) { rab[++tot]=x; } inline int query(int rt,int l,int r,int pos,int f) { if(!rt)re 0; if(l==r) re sum[rt][f]; int mid=(l+r)>>1; if(pos<=mid)re query(ls[rt],l,mid,pos,f); else re query(rs[rt],mid+1,r,pos,f); } inline void add(int &rt,int l,int r,int pos,int vvl,int f) { if(!rt) rt=New(); if(l==r) { sum[rt][f]+=vvl; re ; } int mid=(l+r)>>1; if(pos<=mid)add(ls[rt],l,mid,pos,vvl,f); else add(rs[rt],mid+1,r,pos,vvl,f); } inline int merge(int x,int y,int l,int r) { if(!x||!y)re x+y; if(l==r) { sum[x][0]+=sum[y][0]; sum[x][1]+=sum[y][1]; Throw(y); re x; } int mid=(l+r)>>1; ls[x]=merge(ls[x],ls[y],l,mid); rs[x]=merge(rs[x],rs[y],mid+1,r); Throw(y); re x; } }T; struct Tree_lca { int top[maxn],size[maxn],son[maxn],dep[maxn],fa[maxn]; inline void dfs(int x) { dep[x]=dep[fa[x]]+(size[x]=1); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v!=fa[x]) { fa[v]=x; dfs(v); size[x]+=size[v]; if(size[v]>size[son[x]])son[x]=v; } } } inline void dfs2(int x,int topf) { top[x]=topf; if(son[x]) { dfs2(son[x],topf); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(!top[v]) dfs2(v,v); } } } inline int Lca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])x^=y^=x^=y; x=fa[top[x]]; } re dep[x]<dep[y]?x:y; } }S; inline void dfs(int x) { for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v!=S.fa[x]) { dfs(v); if(x==1&&v==2) x=1; T.rt[x]=T.merge(T.rt[x],T.rt[v],1,maxz); } } for(int i=T.first[x];i;i=T.st[i].nt) T.add(T.rt[x],1,maxz,T.st[i].val,T.st[i].op,T.st[i].flag); ans[x]=T.query(T.rt[x],1,maxz,S.dep[x]+val[x]+maxl,0); ans[x]+=T.query(T.rt[x],1,maxz,val[x]-S.dep[x]+maxl,1); } int main() { // freopen("in.txt","r",stdin); int x,y,z; rd(n),rd(m); inc(i,2,n) { rd(x),rd(y); add(x,y); } S.dfs(1); S.dfs2(1,n+1); inc(i,1,n) rd(val[i]); inc(i,1,m) { rd(x),rd(y); int lca=S.Lca(x,y),flca=S.fa[lca]; T.insert(x,S.dep[x]+maxl,1,0);T.insert(flca,S.dep[x]+maxl,-1,0); T.insert(y,S.dep[x]-(S.dep[lca]<<1)+maxl,1,1);T.insert(lca,S.dep[x]-(S.dep[lca]<<1)+maxl,-1,1); } dfs(1); inc(i,1,n) printf("%d ",ans[i]); re 0; }
T3换教室
遇到概率妥妥挂掉
呃……
虽然是模板题
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(long long i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=2005; #define ll long long ll n,m,v,e; ll mp[maxn][maxn],c[maxn],d[maxn]; double f[maxn][maxn][2],p[maxn]; inline void floyd() { inc(k,1,v) inc(i,1,v) inc(j,1,v) mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]); } int main() { // freopen("in.txt","r",stdin); rd(n),rd(m),rd(v),rd(e); ll x,y,z; inc(i,1,n)rd(c[i]); inc(i,1,n)rd(d[i]); inc(i,1,n)scanf("%lf",&p[i]); memset(mp,0x3f3f3f3f,sizeof mp); inc(i,1,v)mp[i][i]=0; inc(i,1,e) { rd(x),rd(y); rd(z); mp[x][y]=mp[y][x]=min(mp[x][y],z); } inc(i,1,n)inc(j,0,m)f[i][j][1]=f[i][j][0]=21174444; f[1][0][0]=0; f[1][1][1]=0; floyd(); inc(i,2,n) inc(j,0,m) { f[i][j][0]=min(f[i-1][j][0]+mp[c[i-1]][c[i]],f[i-1][j][1]+(1-p[i-1])*mp[c[i-1]][c[i]]+p[i-1]*mp[d[i-1]][c[i]]); if(j)f[i][j][1]=min(f[i-1][j-1][0]+(1-p[i])*mp[c[i-1]][c[i]]+p[i]*mp[c[i-1]][d[i]], f[i-1][j-1][1]+(1-p[i])*(1-p[i-1])*mp[c[i-1]][c[i]] +p[i-1]*(1-p[i])*mp[d[i-1]][c[i]]+(1-p[i-1])*p[i]*mp[c[i-1]][d[i]]+p[i-1]*p[i]*mp[d[i-1]][d[i]]); } double ans=2147483647; inc(i,0,m) ans=min(ans,min(f[n][i][0],f[n][i][1])); printf("%.2lf",ans); re 0; }
day 2
T1 组合数问题
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define dec(i,l,r) for(int i=l;i>=r;--i) const int maxn=2005; int n,m,k,P,sum[maxn][maxn],c[maxn][maxn]; int main() { // freopen("b.in","r",stdin); int T; rd(T);rd(P); c[0][0]=1; c[1][1]=c[1][0]=1; inc(i,2,2000) { c[i][0]=1; inc(j,1,i) { c[i][j]=(c[i-1][j-1]+c[i-1][j])%P; sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(c[i][j]==0); } sum[i][i+1]=sum[i][i]; } int x,y; while(T--) { rd(x),rd(y); if(y>x)y=x; printf("%d\n",sum[x][y]); } re 0; }
T2 蚯蚓
三个优队的故事
#include<bits/stdc++.h> #define re return #define dec(i,l,r) for(int i=l;i>=r;--i) #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e5+5; #define ll long long queue<ll>q1,q2,q3; ll n,m,q,u,v,t,a[maxn],c[8000005]; double p; inline ll Get_max() { ll na,nb,nc; na=nb=nc=-99999999999999999; if(!q1.empty())na=q1.front(); if(!q2.empty())nb=q2.front(); if(!q3.empty())nc=q3.front(); if(na>nb) { if(na>nc){q1.pop();re na;} else {q3.pop();re nc;} } else { if(nb>nc) {q2.pop();re nb;} else {q3.pop();re nc;} } } int main() { // freopen("in.txt","r",stdin); scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t); p=1.0*u/v;; inc(i,1,n) { rd(a[i]); } sort(a+1,a+n+1); dec(i,n,1)q1.push(a[i]); ll ic=0; inc(i,1,m) { ll T=Get_max(); T+=ic; if(!(i%t))printf("%lld ",T); ic+=q; ll ta=(((int)(T*p))-ic); ll tb=(T-((int)(T*p)))-ic; if(ta>tb) swap(ta,tb); q2.push(tb); q3.push(ta); } printf("\n"); int cnt=0; while(!q1.empty())c[++cnt]=q1.front(),q1.pop(); while(!q2.empty())c[++cnt]=q2.front(),q2.pop(); while(!q3.empty())c[++cnt]=q3.front(),q3.pop(); sort(c+1,c+cnt+1); inc(i,1,(n+m)/t) { printf("%lld ",c[n+m-i*t+1]+ic); } re 0; }
T3 愤怒的小鸟
数据很小,状压
先处理出最多n^2的线
当然还阔以随机化
#include<bits/stdc++.h> #define re return #define st static #define C c=getchar() #define mem(a,b) memset((a),(b),sizeof(a)) #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) const double EPS=1e-9; template<typename T>inline void read(T&x) { char c;bool f=0; while((C)<'0'||c>'9')if(c=='-')f=1; x=c^48; while((C)>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48); if(f)x=-x; } using namespace std; int t,n,m,best=0x3f3f3f3f,vis[20],mp[20]; double a,b; struct node { double x,y; }e[20]; void cala(double x1,double y1,double x2,double y2) { a=(y1*x2-y2*x1)/(x1*x2*(x1-x2)); b=(y1-a*x1*x1)/x1; } int main() { // freopen("in.txt","r",stdin); srand(time(NULL)); inc(i,1,20) mp[i]=1<<(i-1); read(t); while(t--) { best=0x3f3f3f3f; read(n),read(m); for(int i=1;i<=n;i++)scanf("%lf%lf",&e[i].x,&e[i].y); inc(zz,1,60) { mem(vis,0); random_shuffle(e+1,e+n+1); int ans=0; inc(i,1,n) { if(vis[i])continue; vis[i]=1; inc(j,i+1,n) { if(vis[j])continue; if(e[i].x==e[j].x)continue; b=(e[i].y-e[j].y*(e[i].x*e[i].x)/(e[j].x*e[j].x))/(e[i].x-(e[i].x*e[i].x)/e[j].x); a=(e[i].y-e[i].x*b)/(e[i].x*e[i].x); if(a>=-EPS)continue; vis[j]=1; inc(k,j+1,n)if(fabs(e[k].y-a*e[k].x*e[k].x-b*e[k].x)<EPS)vis[k]=1; break; } ans++; } best=min(best,ans); if(best==1)break; } printf("%d\n",best); } re 0; }
每次枚举时,枚举一下当前未包含的点
#include<bits/stdc++.h> #define re return #define st static #define C c=getchar() #define mem(a,b) memeset((a),(b),sizeof(a)) #define inc(i,l,r,c) for(int i=l;i<=r;i+=c) #define dec(i,l,r,c) for(int i=l;i>=r;i-=c) const double EPS=1e-6; template<typename T>inline void read(T&x) { char c;bool f=0; while((C)<'0'||c>'9')if(c=='-')f=1; x=c^48; while((C)>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48); if(f)x=-x; } using namespace std; int t,n,m,dp[1<<20],vmp[1<<20],line[20][20]; double a,b,x[20],y[20]; void cala(double x1,double y1,double x2,double y2) { a=(y1*x2-y2*x1)/(x1*x2*(x1-x2)); b=(x1*x1*y2-x2*x2*y1)/(x1*x2*(x1-x2)); } int main() { // freopen("in.txt","r",stdin); for(int i=0;i<(1<<18);i++){ int j=1;for(;j<=18 && i&(1<<(j-1));j++);vmp[i]=j;} for(int i=1;i<=18;i++)line[i][0]=1<<(i-1); read(t); while(t--) { read(n),read(m); int ALL=(1<<n)-1; for(int i=1;i<=ALL;i++)dp[i]=1111111111; inc(i,1,n,1)inc(j,1,n,1)line[i][j]=0; int cnt=0; for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]); for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { if(x[i]==x[j])continue; cala(x[i],y[i],x[j],y[j]); if(a>=0)continue; for(int k=1;k<=n;++k) if(fabs(y[k]-a*x[k]*x[k]-b*x[k])<EPS)line[i][j]|=line[k][0]; } } for(int i=0;i<(1<<n);i++) { int j=vmp[i]; for(int k=0;k<=n;k++) dp[i|line[j][k]]=min(dp[i|line[j][k]],dp[i]+1); } printf("%d\n",dp[(1<<n)-1]); } re 0; }
四.noip2015
day 1
T1 神奇的幻方
按照说的做
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,l,r) for(int i=l;i>=r;i--) template<typename T>inline void read(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } using namespace std; int n,a[50][50]; int main() { read(n); int v=1,x=1,y=(n+1)>>1,z=n*n;a[x][y]=1; while(++v<=z) { if(x==1&&y!=n)x=n,y++; else if(x!=1&&y==n)x--,y=1; else if(x==1)x++; else { if(!a[x-1][y+1])x--,y++; else x++; } if(x>n)x=1; if(y>n)y=1; a[x][y]=v; } inc(i,1,n) { inc(j,1,n)printf("%d ",a[i][j]); putchar('\n'); } re 0; }
T2 信息传递
找最小环
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=2e5+5; int n,m,d[maxn],hd[maxn]; struct node{ int to,nt; }e[maxn<<1]; int k; inline void add(int x,int y){e[++k]=(node){y,hd[x]};hd[x]=k;++d[y];} int c[maxn]; inline void topo() { queue<int>q; inc(i,1,n)if(!d[i])q.push(i) ; while(!q.empty()) { int x=q.front(); c[x]=1; q.pop(); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(!(--d[v]))q.push(v); } } } int cnt,ans; inline void dfs(int x) { if(c[x])re ; c[x]=1;++cnt; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; dfs(v); } } int main() { freopen("b.in","r",stdin); rd(n); int x; inc(i,1,n) { rd(x); add(i,x); } topo(); ans=n; inc(i,1,n) if(!c[i]) { cnt=0; dfs(i); ans=min(ans,cnt); } printf("%d",ans); re 0; }
T3 斗地主
玄学的搜索
#include<bits/stdc++.h> #define re return #define st static #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) template<typename T>inline void read(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')c=getchar(); x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } using namespace std; int a[20],t,n,ans; void doudizhu(int x) { if(x>ans)re; int k=0; inc(i,3,14)//单顺子 if(!a[i])k=0; else { k++; if(k>=5) { inc(j,0,k-1)a[i-j]--; doudizhu(x+1); inc(j,0,k-1)a[i-j]++; } } k=0; inc(i,3,14)//双顺子 if(a[i]<=1)k=0; else { k++; if(k>=3) { inc(j,0,k-1)a[i-j]-=2; doudizhu(x+1); inc(j,0,k-1)a[i-j]+=2; } } k=0; inc(i,3,14)//三顺子 if(a[i]<=2)k=0; else { k++; if(k>=2) { inc(j,0,k-1)a[i-j]-=3; doudizhu(x+1); inc(j,0,k-1)a[i-j]+=3; } } //------------------------------------------------------------------------------------------------------------------------------ inc(i,2,14) { if(a[i]==4)//四带 { a[i]-=4; inc(j,2,14) if(a[j]>=2) { a[j]-=2; inc(z,2,14) { if(a[z]>=2) { a[z]-=2; doudizhu(x+1); a[z]+=2; } } a[j]+=2; } inc(j,2,15) //四带二 { if(!a[j])continue; a[j]--; inc(z,2,15) if(a[z]) { a[z]--; doudizhu(x+1); a[z]++; } a[j]++; } doudizhu(x+1); a[i]+=4; } if(a[i]>=3)//三带 { a[i]-=3; inc(j,2,14) if(a[j]>=2)//三带二 { a[j]-=2; doudizhu(x+1); a[j]+=2; } inc(j,2,15) if(a[j]&&j!=i)//三带一 { a[j]--; doudizhu(x+1); a[j]++; } doudizhu(x+1); a[i]+=3; } } //------------------------------------------------------------------------------------------------------------------------ inc(i,2,15)if(a[i])x++; ans=min(ans,x); } void vcc() { int x,y; ans=23; memset(a,0,sizeof(a)); inc(i,1,n) { read(x),read(y); if(!x)a[15]++; else if(x==1)a[14]++; else a[x]++; } doudizhu(0); printf("%d\n",ans); } int main() { // freopen("testdata(1).in","r",stdin); /* freopen("in.txt","r",stdin);*/ read(t),read(n); while(t--)vcc(); re 0; }
day 2
T1 跳石头
贪心+二分
#include<bits/stdc++.h> #define re return #define sta static #define supervisor liangsiyi.mz #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(iny i=l;i>=r;--i) using namespace std; int n,k,l=1,r,m,ll,size,a[50005]; inline int read() { int date=0;char c=' '; while('0'>c||c>'9')c=getchar(); while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();} re date; } bool jd(int floor) { int tot=0,now=0; inc(i,1,n+1) if(a[i]-a[now]<floor)tot++; else now=i; if(tot<=m)re 1; else re 0; } int main() { ll=read(),n=read(),m=read(); inc(i,1,n) a[i]=read(); a[n+1]=ll; if(n-m==0)r=ll; else r=ll/(n-m)+1; while(l<=r) { int mid=(l+r)/2; if(jd(mid))l=mid+1; else r=mid-1; } printf("%d",l-1); re 0; }
T2 子串
dp
去年奇奇怪怪地写了过去
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long const int maxn=1e3+3; ll n,m,k,f[2][205][205][2],P=1000000007; char s1[maxn],s2[maxn]; int main() { //freopen("b.in","r",stdin); rd(n),rd(m),rd(k); scanf("%s",s1+1); scanf("%s",s2+1); int now=1,pre=0; f[0][0][0][0]=f[1][0][0][0]=1; inc(i,1,n) { inc(j,1,m) inc(kk,1,k) { f[now][j][kk][0]=(f[pre][j][kk][0]+f[pre][j][kk][1])%P; if(s1[i]==s2[j]) { f[now][j][kk][1]=(f[pre][j-1][kk][1]+f[pre][j-1][kk-1][0]+f[pre][j-1][kk-1][1])%P; } else f[now][j][kk][1]=0; } now^=pre^=now^=pre; } printf("%lld",(f[n&1][m][k][0]+f[n&1][m][k][1])%P); re 0; }
T3 运输计划
二分+树上差分
#include<bits/stdc++.h> #define inc(i,l,r) for(int i=l;i<=r;++i) #define reg register #define re return using namespace std; const int maxn=300005,maxm=600005; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48); if(f)x=-x; } int n,m,k,k1,l,r,num,res,maxlen; int to[maxm],nt[maxm],to1[maxm],val[maxm],nt1[maxm],head1[maxm],dis[maxn],head[maxn],faa[maxn],vis[maxn],cnt[maxn],a[maxn]; struct node { int x,y,lca,dis; }ask[maxn]; inline void add(int x=0,int y=0,int z=0) { rd(x),rd(y),rd(z); to[++k]=y;nt[k]=head[x];val[k]=z;head[x]=k; to[++k]=x;nt[k]=head[y];val[k]=z;head[y]=k; r+=z; } inline void add1(int x,int y) { nt1[++k1]=head1[x];head1[x]=k1;to1[k1]=y; nt1[++k1]=head1[y];head1[y]=k1;to1[k1]=x; } //-----------------------------------------tarjan------------------------------------------------// inline int find(int x){re x==faa[x]?x:faa[x]=find(faa[x]); } void tarjan(int u,int fa) { for(int i=head[u];i;i=nt[i]) { int v=to[i],w=dis[u]+val[i]; if(v==fa)continue; dis[v]=w; a[v]=w-dis[u]; tarjan(v,u); int f1=find(v); int f2=find(u); if(f1!=f2) faa[f1]=find(f2); vis[v]=1; } for(int i=head1[u];i;i=nt1[i]) { int v=to1[i]; if(vis[v]) { int now=(i+1)>>1; ask[now].lca=find(faa[v]); ask[now].dis=dis[v]+dis[u]-(dis[ask[now].lca]<<1); maxlen=max(ask[now].dis,maxlen); } } } //--------------------------------------------差分-----------------------------------------------// void dfvv(int u,int fa) { for(int i=head[u];i;i=nt[i]) { int v=to[i]; if(v!=fa) { dfvv(v,u); cnt[u]+=cnt[v]; } } if(cnt[u]==num&&a[u]>res)res=a[u]; } inline bool check(int x) { memset(cnt,0,sizeof(cnt)); res=num=0; for(int i=1;i<=m;i++) if(ask[i].dis>x) cnt[ask[i].x]++,cnt[ask[i].y]++,cnt[ask[i].lca]-=2,num++; dfvv(1,0); re maxlen-res<=x; } //--------------------------------------------main-----------------------------------------------// int main() { //freopen("testdata(2).in","r",stdin); // freopen("in.txt","r",stdin); rd(n),rd(m); inc(i,2,n)add(); inc(i,1,m){ rd(ask[i].x),rd(ask[i].y); add1(ask[i].x,ask[i].y); } inc(i,1,n)faa[i]=i; tarjan(1,0); while(l<=r) { int mid=(l+r)>>1; if(check(mid))r=mid-1; else l=mid+1; } printf("%d",l); re 0; }
五.noip2014
day 1
T1 生活大爆炸版石头剪刀布
zz 模拟
直接模拟打表就好
反正我看不出什么规律
#include<bits/stdc++.h> #define re return #define sta static #define supervisor liangsiyi.mz #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) using namespace std; int n,cost[5][5]={0,0,1,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,1,0,0,0}; int a[205],b[205]; inline int read() { int date=0;char c=' '; while('0'>c||c>'9')c=getchar(); while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();} re date; } void dfs() { } int main() { int x,y,sa=0,sb=0;; scanf("%d%d%d",&n,&x,&y); inc(i,1,x) scanf("%d",&a[i]); inc(i,1,y) scanf("%d",&b[i]); int i=0,j=0; inc(k,1,n) { i=(i+1)>x?1:i+1; j=(j+1)>y?1:j+1; sa+=cost[a[i]][b[j]]; sb+=cost[b[j]][a[i]]; } printf("%d %d",sa,sb); }
T2 联合权值
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } typedef long long ll; const int maxn=2e5+5; ll n,m,w[maxn],P=10007,hd[maxn]; struct node{ int to,nt; }e[maxn<<1]; int k; inline void add(int x,int y) { e[++k]=(node){y,hd[x]};hd[x]=k; } ll ans=0,mmm; inline void dfs(int x,int fa) { ll sum=0,maxx=w[fa]; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa)continue; dfs(v,x); ans=(ans+(w[fa]+sum)*w[v])%P; mmm=max(mmm,w[v]*maxx); maxx=max(maxx,w[v]); sum=(sum+w[v])%P; } } int main() { freopen("a.in","r",stdin); int x,y; rd(n); inc(i,2,n) { rd(x),rd(y); add(x,y); add(y,x); } inc(i,1,n)rd(w[i]); dfs(1,0); printf("%lld %lld",mmm,ans*2ll%P); re 0; }
T3 飞扬的小鸟
背包
#include<bits/stdc++.h> #define re return #define sta static #define supervisor liangsiyi.mz #define ll long long #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) #define M 0x3f3f3f3f using namespace std; int n,m,k,e[10005],xx[10005],yy[10005],l[10005],h[10005],f[10005][2005],x,y,z,ans; inline int read() { int date=0;char c=' '; while('0'>c||c>'9')c=getchar(); while('0'<=c&&c<='9'){date=(date<<3)+(date<<1)+(c^48);c=getchar();} re date; } int main() { // freopen("testdata1.in","r",stdin); n=read(),m=read(),k=read(); inc(i,1,n)h[i]=m,l[i]=1; inc(i,1,n)xx[i]=read(),yy[i]=read(); inc(i,1,k) {x=read();y=read();z=read(); e[x]=1;l[x]=y+1;h[x]=z-1;} memset(f,0x3f3f3f3f,sizeof(f)); inc(i,1,m)f[0][i]=0; inc(i,1,n) { inc(j,xx[i]+1,m+xx[i]) //浠?1 寮€ 濮?锛?鍚?鍒?浼?閬?婕? f[i][j]=min(f[i-1][j-xx[i]]+1,f[i][j-xx[i]]+1); inc(j,m+1,m+xx[i]) f[i][m]=min(f[i][m],f[i][j]); inc(j,1,m-yy[i]) f[i][j]=min(f[i][j],f[i-1][j+yy[i]]); inc(j,1,l[i]-1) f[i][j]=M; inc(j,h[i]+1,m) f[i][j]=M; } int sum=0x3f3f3f3f; inc(i,1,m) if(f[n][i])sum=min(sum,f[n][i]); if(sum!=0x3f3f3f3f)printf("1\n%d",sum); else { dec(i,n,1) { y=0; inc(j,1,m) if(f[i][j]<M) { inc(k,1,i) if(e[k])ans++; printf("0\n%d",ans); re 0; } } } re 0; }
day 2
T1 无线网络发射器选址
二维前缀和
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } using namespace std; int n,m,d,a[150][150],ans,cnt; int main() { rd(d); rd(n); int k,x,y,l,r; inc(i,1,n) { rd(x),rd(y); rd(k); a[x+1][y+1]=k; } inc(i,1,129)inc(j,1,129) a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; inc(i,1,129)inc(j,1,129) { l=i-d-1<0?0:i-d-1; r=i+d>129?129:i+d; x=j-d-1<0?0:j-d-1; y=j+d>129?129:j+d; k=a[y][r]-a[y][l]-a[x][r]+a[x][l]; if(k>ans)ans=k,cnt=1; else if(ans==k) ++cnt; } printf("%d %d",cnt,ans); re 0; }
貌似写法有点奇怪
T2 寻找道路
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e4+5,maxm=2e5+5; int n,m,hd[maxn],vis[maxn],ok[maxn]; struct node{ int to,nt; }e[maxm<<1]; int k; inline void add(int x,int y){ e[++k]=(node){y,hd[x]};hd[x]=k; } inline void dfs(int x) { vis[x]=ok[x]=1; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(!vis[v])dfs(v); } } int dis[maxn],inf=5e5; struct nide{ int x,val; inline bool operator<(nide b)const { re val>b.val; } }; int s,t; inline void dij() { inc(i,1,n)dis[i]=inf; priority_queue<nide>q; dis[t]=0; q.push((nide){t,0}); while(!q.empty()) { nide u=q.top(); q.pop(); int x=u.x; if(dis[x]!=u.val)continue; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(ok[v]&&dis[v]>dis[x]+1) { dis[v]=dis[x]+1; q.push((nide){v,dis[v]}); } } } if(dis[s]==inf)printf("-1"); else printf("%d",dis[s]); } int main() { freopen("a.in","r",stdin); rd(n),rd(m); int x,y; inc(i,1,m) { rd(x),rd(y); add(y,x); } rd(s),rd(t); dfs(t); vis[s]=1; inc(i,1,n) if(!vis[i]) { for(int j=hd[i];j;j=e[j].nt) { int v=e[j].to; ok[v]=0; } } dij(); }
T3 解方程
多取几遍mod就好
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long ll mod[4]={47809,47807,102931,102929}; ll a[105][4],n,m; char s[10005]; int cnt,ans[1000005]; bool vis[1000005]; inline bool check(int x) { for(int i=0;i<4;++i) { ll tmp=a[n][i]; for(int j=n-1;j>=0;--j) tmp=(tmp*x+a[j][i])%mod[i]; if(tmp) { for(int j=x;j<=m;j+=mod[i]) vis[j]=1; re 0; } } re 1; } int main() { int len; rd(n),rd(m); inc(i,0,n) { scanf("%s",s+1); len=strlen(s+1); inc(k,0,3) { ll tmp=0,flag=1; inc(j,1,len) if(s[j]=='-')flag=-1; else tmp=(tmp*10+(s[j]^48))%mod[k]; a[i][k]=tmp*flag; } } inc(i,1,m) if(!vis[i]&&check(i))ans[++cnt]=i; printf("%d\n",cnt); inc(i,1,cnt) printf("%d\n",ans[i]); re 0; }