2019东北四省赛
B题
暴力题,通过维护数组表示在i位置能够取到数的大小
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; int l[N]; vector<int> num[N]; int a[N],b[N]; ll f[N]; ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n,m; cin>>n>>m; int i; memset(f,0,sizeof f); for(i=0;i<=m;i++) num[i].clear(); for(i=1;i<=m;i++) cin>>l[i]; for(i=1;i<=n;i++){ cin>>a[i]>>b[i]; num[b[i]].push_back(a[i]); } int mi=0x3f3f3f3f; int mx=0; for(i=1;i<=m;i++){ sort(num[i].begin(),num[i].end()); reverse(num[i].begin(),num[i].end()); if((int)num[i].size()<l[i]) continue; for(int j=0;j<(int)num[i].size();j++){ f[max(j+1,l[i])]+=num[i][j]; } mi=min(mi,(int)l[i]); mx=max(mx,(int)l[i]); } ll ans=0,d=1; double tmp=0; ll sum=0; for(i=mi;i<=mx;i++){ sum+=f[i]; if(1.0*sum/i>tmp){ ans=sum; d=i; tmp=1.0*sum/i; } } ll dd=gcd(ans,d); ans/=dd; d/=dd; cout<<ans<<"/"<<d<<endl; } return 0; }
C题
因为double有精度问题,所以不好去重,改成一般式就行
#include<bits/stdc++.h> #define LL long long using namespace std; const int maxn=1e6+5; struct Point { LL x,y; }pt1,pt2; struct Line { LL a,b,c; Line(Point s,Point e) { a=s.y-e.y; b=e.x-s.x; c=s.x*e.y-s.y*e.x; } }; LL gcd(LL a,LL b) { LL ans=(!b?a:gcd(b,a%b)); if(ans==0) return 1; return ans; } pair<LL,LL>p1; pair<pair<LL,LL>,LL>p2; map<pair<LL,LL>,LL>mp1; map<pair<pair<LL,LL>,LL>,LL>mp2; int main() { int T; scanf("%d",&T); while(T--) { mp1.clear(); mp2.clear(); LL n; scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld%lld%lld%lld",&pt1.x,&pt1.y,&pt2.x,&pt2.y); Line l=Line(pt1,pt2); LL g=gcd(l.a,l.b); LL a=l.a/g,b=l.b/g,c=l.c/g; p1=make_pair(a,b); p2=make_pair(p1,c); mp1[p1]++; mp2[p2]++; } LL ans=(LL)(n*(n-1)/2); for(auto it=mp1.begin();it!=mp1.end();it++) ans-=(it->second)*((it->second)-1)/2; for(auto it=mp2.begin();it!=mp2.end();it++) ans+=(it->second)*((it->second)-1)/2; printf("%lld\n",ans); } return 0; }
D题
虚树
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+10; vector<int> num; int dfn[N],id[N],tot,idx; int h[N],ne[N],e[N],q[N]; int n,m,depth[N],times; int f[N][30],u[N],v[N],k[N],opt[N]; int valf[N],pid[N]; ll val[N]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void init(){ num.clear(); memset(h,-1,sizeof h); idx=0; tot=0; for(int i=1;i<N;i++){ k[i]=0; val[i]=0; pid[i]=0; valf[i]=0; } } void dfs(int u,int fa){ dfn[u]=++times; f[u][0]=fa; depth[u]=depth[fa]+1; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); } } void pp(){ int i,j; for(i=1;i<=27;i++){ for(j=1;j<=n;j++){ f[j][i]=f[f[j][i-1]][i-1]; } } } bool cmp(int a,int b){ return dfn[a]<dfn[b]; } void addx(int a,int b){ valf[b]=a; pid[b]=++tot; } int lca(int a,int b){ if(depth[a]<depth[b]) swap(a,b); int i; for(i=27;i>=0;i--){ if(depth[f[a][i]]>=depth[b]){ a=f[a][i]; } } if(a==b) return a; for(i=27;i>=0;i--){ if(f[a][i]!=f[b][i]){ a=f[a][i]; b=f[b][i]; } } return f[a][0]; } void build(){ sort(num.begin(),num.end()); num.erase(unique(num.begin(),num.end()),num.end()); sort(num.begin(),num.end(),cmp); int tt=1; q[tt]=1; int i; for(i=0;i<(int)num.size();i++){ if(num[i]==1) continue; int p=lca(num[i],q[tt]); if(p!=q[tt]){ while(dfn[p]<dfn[q[tt-1]]){ addx(q[tt-1],q[tt]); tt--; } if(dfn[p]!=dfn[q[tt-1]]){ addx(p,q[tt]); q[tt]=p; } else{ addx(p,q[tt]); tt--; } } q[++tt]=num[i]; } for(i=1;i<tt;i++){ addx(q[i],q[i+1]); } } ll get(int x,int d,int choice){ if(choice==1){ return x+d; } if(choice==2){ return (x^d); } if(choice==3){ return (x>=d?x-d:x); } } void modify(int x,int y,int d,int choice){ int tmp[2]={x,y}; int p=lca(x,y); for(int i=0;i<2;i++){ int ans=tmp[i]; while(ans!=p){ val[ans]=get(val[ans],d,choice); val[n+pid[ans]]=get(val[n+pid[ans]],d,choice); //cout<<p<<" "<<valf[ans]<<endl; ans=valf[ans]; } } val[p]=get(val[p],d,choice); } ll sum,xorsum,maxv,minv,minabs; ll update(ll x,int d,int sz){ sum+=1ll*sz*x; xorsum=xorsum^(sz%2*x); maxv=max(maxv,x); minv=min(minv,x); minabs=min(minabs,abs(x-d)); } ll query(int x,int y,int d,int choice){ int tmp[2]={x,y}; int p=lca(x,y); sum=0,xorsum=0,maxv=0,minv=1<<30,minabs=1<<30; for(int i=0;i<2;i++){ int ans=tmp[i]; while(ans!=p){ int sz=depth[ans]-depth[valf[ans]]-1; update(val[ans],d,1); if(sz){ update(val[n+pid[ans]],d,sz); } ans=valf[ans]; } } update(val[p],d,1); if(choice==4){ return sum; } if(choice==5){ return xorsum; } if(choice==6){ return maxv-minv; } if(choice==7) return minabs; } int main(){ //ios::sync_with_stdio(false); int t; cin>>t; while(t--){ scanf("%d%d",&n,&m); init(); int i,j; for(i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } dfs(1,0); pp(); for(i=1;i<=m;i++){ scanf("%d%d%d",&opt[i],&u[i],&v[i]); num.push_back(u[i]); num.push_back(v[i]); if(opt[i]<=3||opt[i]==7){ scanf("%d",&k[i]); } } build(); for(i=1;i<=m;i++){ if(opt[i]<=3){ modify(u[i],v[i],k[i],opt[i]); } else{ printf("%lld\n",query(u[i],v[i],k[i],opt[i])); } } } }
F题
博弈
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; int f[N][10]; int n,m; int b[N],du[N][10]; string s,t; vector<int> num[N]; int real1[N]; int pre(int x){ if(x==1) return 6; else return x-1; } void solve(){ queue<pll> q; int i,j; for(i=1;i<=n;i++){ if(du[i][1]==0){ for(j=1;j<=6;j++){ if(s[j]=='A'){ f[i][j]=1; q.push({i,j}); } else{ f[i][j]=0; q.push({i,j}); } } } } while(q.size()){ auto x=q.front(); q.pop(); for(auto e:num[x.first]){ if(f[e][pre(x.second)]==-1){ if(f[x.first][x.second]==b[pre(x.second)]){ f[e][pre(x.second)]=b[pre(x.second)]; q.push({e,pre(x.second)}); } else{ du[e][pre(x.second)]--; if(du[e][pre(x.second)]==0){ f[e][pre(x.second)]=b[pre(x.second)]^1; q.push({e,pre(x.second)}); } } } } } } int main(){ ios::sync_with_stdio(false); int T; cin>>T; while(T--){ cin>>n>>m; memset(f,-1,sizeof f); memset(du,0,sizeof du); int i,j; for(i=0;i<=n;i++) num[i].clear(); for(i=1;i<=m;i++){ int a,b; cin>>a>>b; num[b].push_back(a); for(j=1;j<=6;j++){ du[a][j]++; } } cin>>s>>t; s=" "+s; t=" "+t; for(i=1;i<=6;i++){ real1[i]=s[i]-'A'; b[i]=(t[i]-'0')^real1[i]; } solve(); for(i=1;i<=n;i++){ if(f[i][1]==-1){ cout<<'D'; } else if(f[i][1]==1){ cout<<'B'; } else{ cout<<'A'; } } cout<<endl; } }
H题
线段树维护差分数组,树状数组维护原数组的变更
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; struct node{ int l,r; ll sum; }tr[N<<2]; ll tr2[N]; int a[N],b[N]; int n,m; int lowbit(int x){ return x&-x; } ll sum(int x){ ll ans=0; int i; for(i=x;i;i-=lowbit(i)){ ans+=tr2[i]; } return ans; } void add(int x,int c){ int i; for(i=x;i<=n;i+=lowbit(i)){ tr2[i]+=c; } } void pushup(int u){ tr[u].sum=max(tr[u<<1].sum,0ll)+max(tr[u<<1|1].sum,0ll); } void build(int u,int l,int r){ if(l==r){ tr[u]={l,r,a[l]}; } else{ tr[u]={l,r,0}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); pushup(u); } } void modify(int u,int l,int x){ if(tr[u].l==tr[u].r){ tr[u].sum+=x; return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,x); else{ modify(u<<1|1,l,x); } pushup(u); } ll query(int u,int l,int r){ if(tr[u].l>=l&&tr[u].r<=r){ return max(tr[u].sum,0ll); } int mid=tr[u].l+tr[u].r>>1; ll ans=0; if(l<=mid) ans+=query(u<<1,l,r); if(r>mid) ans+=query(u<<1|1,l,r); return ans; } int main(){ //ios::sync_with_stdio(false); int t; cin>>t; while(t--){ scanf("%d%d",&n,&m); int i; for(i=1;i<=n;i++) tr2[i]=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } for(i=n;i>=1;i--){ a[i]-=a[i-1]; } for(i=1;i<=n;i++){ add(i,a[i]); } build(1,1,n); for(i=1;i<=m;i++){ int opt; scanf("%d",&opt); if(opt==1){ int l,r,k; scanf("%d%d%d",&l,&r,&k); modify(1,l,k); add(l,k); if(r<n){ modify(1,r+1,-k); add(r+1,-k); } } else{ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",sum(l)+query(1,1,r)-query(1,1,l)); } } } return 0; }
J题
签到
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=110; int a[N]; int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n; cin>>n; int i,j; for(i=1;i<=n;i++){ cin>>a[i]; } for(i=1;i<=50;i++){ int flag=0; for(j=1;j<=n;j++){ if(j==1){ if(i<3*a[j]) flag=1; } else{ if(i<a[j]+1){ flag=1; } } } if(!flag&&i%2==0){ cout<<i<<endl; break; } } } return 0; }
没有人不辛苦,只有人不喊疼