传送门
\(HMAPPY2\)
咕
话说这题居然卡\(scanf\)的么???
int T;cin>>T;
while(T--){cin>>n>>a>>b>>k;puts(n/a+n/b-n/(a*b/__gcd(a,b))*2>=k?"Win":"Lose");
}
\(CHEFING\)
咕咕
int T;scanf("%d",&T);
while(T--){scanf("%d",&n),res=0;fp(i,0,25)flag[i]=1;while(n--){scanf("%s",s+1);fp(i,0,25)cnt[i]=0;fp(i,1,strlen(s+1))cnt[s[i]-'a']=1;fp(i,0,25)flag[i]&=cnt[i];}fp(i,0,25)res+=flag[i];printf("%d\n",res);
}
\(DEPCHEF\)
咕咕咕
int T;scanf("%d",&T);
while(T--){scanf("%d",&n),mx=-1;fp(i,1,n)scanf("%d",&a[i]);a[0]=a[n],a[n+1]=a[1];fp(i,1,n)scanf("%d",&d[i]);d[0]=d[n],d[n+1]=d[1];fp(i,1,n)if(a[i-1]+a[i+1]<d[i])cmax(mx,d[i]);printf("%d\n",mx);
}
\(MAGICJAR\)
咕咕咕咕
int T;scanf("%d",&T);
while(T--){scanf("%d",&n),res=0;fp(i,1,n)scanf("%d",&a[i]),res+=a[i]-1;printf("%lld\n",res+1);
}
\(ARTBALAN\)
发现只与字母出现次数有关。枚举一下最后剩下\(k\)个字母,那么每种字母要剩\(n/k\)个,如果不选代价是\(cnt_i\),选了代价是\(|cnt_i-n/k|\),先假设全选,再找出\(|cnt_i-n/k|-cnt_i\)最小的\(k\)个加上就是了
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
int read(char *s){R int len=0;R char ch;while(((ch=getc())>'Z'||ch<'A'));for(s[++len]=ch;(ch=getc())>='A'&&ch<='Z';s[++len]=ch);return s[len+1]='\0',len;
}
const int N=1e6+5;
char s[N];int cnt[35],a[35],res,tmp,n;
inline int abs(R int x){return x<0?-x:x;}
int main(){
// freopen("testdata.in","r",stdin);for(int T=read();T;--T){n=read(s),res=n+1;memset(cnt,0,104);fp(i,1,n)++cnt[s[i]-'A'];fp(k,1,26)if(n%k==0){tmp=0;fp(i,0,25)tmp+=cnt[i],a[i]=abs(n/k-cnt[i])-cnt[i];sort(a,a+26);fp(i,0,k-1)tmp+=a[i];cmin(res,tmp>>1);}printf("%d\n",res);}return 0;
}
\(MANRECT\)
先询问\((0,0)\),可以求出矩形左下角所在的那条副对角线,同理询问\((0,inf),(inf,inf),(inf,0)\),然后再求出左上角的对角线和右上角的对角线的交点横坐标\(x\)(有可能不是整数,那么下取整),此时询问\((x,inf)\),得到的必然是矩形上边界离\(y=inf\)这条直线的距离,然后就求出矩形右上角的\(y\)坐标了,剩下的代入方程就可以了
话说为啥用\(scanf\)和\(printf\)会\(T\)啊???
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
int read(){R int res,f=1;R char ch;while((ch=getchar())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getchar())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
inline int print(R int x,R int y){cout<<'Q'<<' '<<x<<' '<<y<<endl;fflush(stdout);return read();}
const int inf=1e9;
int a,b,c,d,t,x,y,xx,yy;
int main(){
// freopen("testdata.in","r",stdin);int T=read();while(T--){a=print(0,0),b=print(0,inf),c=print(inf,inf),d=print(inf,0);if(0ll+b+c<inf)t=print(b+1,inf);else t=print((0ll+inf+b-c)>>1,inf);yy=0ll+inf-t,xx=0ll+(inf<<1)-c-yy;y=0ll+xx-inf+d,x=0ll+a-y;cout<<'A'<<' '<<x<<' '<<y<<' '<<xx<<' '<<yy<<endl;fflush(stdout);read();}return 0;
}
\(GUESSRT\)
最优策略应该是先排除最后一个不管,前面一直\(12121212...\),最后一个必选\(1\)
证明的话……我瞎猜的一个结论你叫我证明……
顺便注意如果刚开始\(n>k\)要先进行一次\(2\)操作令\(n\leq k\)
upd:去看了看官方题解,这个似乎应该反过来说,也就是如果只剩一个选\(1\),前面一直按照\(21212121\)的顺序,因为\(21\)的概率显然比\(11\)要大
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
int read(){R int res,f=1;R char ch;while((ch=getchar())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getchar())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
const int N=6e4+5,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){R int res=1;for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;return res;
}
int n,m,k,res,tmp,inv[N];
int main(){
// freopen("testdata.in","r",stdin);inv[0]=inv[1]=1;fp(i,2,N-1)inv[i]=mul(P-P/i,inv[P%i]);for(int T=read();T;--T){n=read(),k=read(),m=read();if(m==1){printf("%d\n",inv[n]);continue;}if(n>k)--m,n=(n-1)%k+1;tmp=ksm(mul(n-1,inv[n]),(m+1)>>1);res=add(P+1-tmp,(m&1^1)?mul(tmp,inv[n+k]):0);printf("%d\n",res);}return 0;
}
\(CHORCKIT\)
咕咕咕咕咕咕咕咕咕
\(challenge\)不写了
\(XDCOMP\)
首先对于一个子树,只有它的异或和为\(x\)或\(0\)才有分割成功的可能
我们记\(f_{u,0/1}\)表示对于\(u\)这棵子树,已经割掉的边为偶数/奇数的方案数,转移的时候,如果当前这条边不割,那么直接转移就是。只有当\(sum_v\)(其中\(sum\)表示子树异或和)为\(0\)且\(v\)的子树里割掉的边为奇数条,或者\(sum_v\)为\(x\)且\(v\)的子树里割掉的边为偶数条,这一条边才允许被割掉。最后记得判一下整棵树的异或和
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
const int N=1e5+5,P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:x;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){R int res=1;for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;return res;
}
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void Add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int f[N][2],g[N][2],sum[N],n,x,res;
void dfs(int u,int fa){f[u][0]=1,f[u][1]=0;go(u)if(v!=fa){dfs(v,u),sum[u]^=sum[v];g[u][0]=g[u][1]=0;if(sum[v]==x){upd(g[u][1],mul(f[u][0],f[v][0])),upd(g[u][0],mul(f[u][1],f[v][0]));}if(sum[v]==0){upd(g[u][1],mul(f[u][1],f[v][1])),upd(g[u][0],mul(f[u][0],f[v][1]));}upd(g[u][0],mul(f[u][0],f[v][0])),upd(g[u][0],mul(f[u][1],f[v][1])),upd(g[u][1],mul(f[u][0],f[v][1])),upd(g[u][1],mul(f[u][1],f[v][0]));f[u][0]=g[u][0],f[u][1]=g[u][1];}
}
int main(){
// freopen("testdata.in","r",stdin);n=read(),x=read();fp(i,1,n)sum[i]=read();for(R int i=1,u,v;i<n;++i)u=read(),v=read(),Add(u,v),Add(v,u);dfs(1,0);if(sum[1]==x)upd(res,f[1][0]);if(sum[1]==0)upd(res,f[1][1]);printf("%d\n",res);return 0;
}
\(MAXTAX\)
缩点之后跑个\(dp\)就可以了
关于同一个联通块内,我们可以先\(sort\)一下,然后枚举有\(i\)个人会因为税款太高而愉悦,那么能收到的最大税款就是\((cnt-i)\times b_{i+1}\)
记得要求的是最大值,计算过程中不需要取模
清零的时候我忘了\(long\ long\)占\(8\)个字节然后计算的时候算错了orz
//minamoto
#include<bits/stdc++.h>
#define R register
#define pb push_back
#define ll long long
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
const int N=2e5+5,M=5e5+5,P=1e9+21;
struct eg{int v,nx;}e[M];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
vector<int>to[N],nod[N];int col[N],dfn[N],low[N],st[N],deg[N],top,cnt,tim;
int q[N],a[N];ll f[N][205],tmp[205],res;
void tarjan(int u){dfn[u]=low[u]=++tim,st[++top]=u;for(R int i=0,s=to[u].size(),v;i<s&&(v=to[u][i]);++i)if(!dfn[v])tarjan(v),cmin(low[u],low[v]);else if(!col[v])cmin(low[u],dfn[v]);if(low[u]==dfn[u])for(++cnt,st[top+1]=0;st[top+1]!=u;--top)col[st[top]]=cnt,nod[cnt].pb(a[st[top]]);
}
int n,m,k;
void clr(){fp(i,1,n)vector<int>().swap(to[i]);fp(i,1,cnt)vector<int>().swap(nod[i]);memset(col,0,(n+1)<<2),memset(dfn,0,(n+1)<<2);memset(deg,0,(cnt+1)<<2),memset(head,0,(cnt+1)<<2);tot=cnt=top=tim=0;
}
void solve(){int h=1,t=0,u;++cnt;fp(i,1,cnt-1){add(i,cnt),++deg[cnt];if(!deg[i])q[++t]=i;memset(f[i],0,(k+1)<<3);}memset(f[cnt],0,(k+1)<<3);while(h<=t){u=q[h++],sort(nod[u].begin(),nod[u].end());fp(j,0,k)tmp[j]=f[u][j];for(R int i=0,s=nod[u].size();i<s;++i)fp(j,0,k-i)cmax(tmp[i+j],f[u][j]+1ll*(s-i)*nod[u][i]);go(u){fp(j,0,k)cmax(f[v][j],tmp[j]);if(!--deg[v])q[++t]=v;}}
}
int main(){
// freopen("testdata.in","r",stdin);for(int T=read();T;--T){n=read(),m=read(),k=read();fp(i,1,n)a[i]=read();for(R int i=1,u,v;i<=m;++i)u=read(),v=read(),to[u].pb(v);fp(i,1,n)if(!dfn[i])tarjan(i);fp(u,1,n)for(R int i=0,s=to[u].size(),v;i<s&&(v=to[u][i]);++i)if(col[u]!=col[v])add(col[u],col[v]),++deg[col[v]];solve();res=0;fp(i,0,k)cmax(res,f[cnt][i]);printf("%lld\n",res%P);clr();}return 0;
}
\(TRDST\)
我怎么又把点分给忘了→_→
首先在每一个点处是可以二分答案的,那么我们现在的问题转化为求到它的距离大于\(mid\)的点数,也可以转化为数到它的距离小于等于\(mid\)的点数
到某个顶点距离小于等于\(k\)的点数……这就是个点分树的经典应用了,我觉得代码比我讲得清楚所以建议自行看代码理解
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
const int N=1e5+5,M=3e6+5;
inline int min(R int x,R int y){return x<y?x:y;}
int pool[M],*pp=pool;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
struct Eg{int sz,nx,d,sgn,*c;}E[M];int Head[N],tc;
int sz[N],mx[N],dep[N],fa[N],q[N],vis[N],size,rt;
int n,a[N];
void findrt(int u,int fa){sz[u]=1,mx[u]=0;go(u)if(v!=fa&&!vis[v])findrt(v,u),sz[u]+=sz[v],cmax(mx[u],sz[v]);cmax(mx[u],size-sz[u]);if(mx[u]<mx[rt])rt=u;
}
void dfs(int u,int sgn,int d){int h=1,t=0;q[++t]=u,dep[u]=d,fa[u]=0;while(h<=t){u=q[h++],++pp[dep[u]];go(u)if(!vis[v]&&v!=fa[u])q[++t]=v,dep[v]=dep[u]+1,fa[v]=u;}int len=dep[q[t]];fp(i,1,t)u=q[i],E[++tc]={len,Head[u],dep[u],sgn,pp},Head[u]=tc;fp(i,1,len)pp[i]+=pp[i-1];pp+=len+1;
}
void solve(int u){vis[u]=1,dfs(u,1,0);int s=size;go(u)if(!vis[v]){dfs(v,-1,1);rt=0,size=sz[v]>sz[u]?s-sz[u]:sz[v],findrt(v,0);solve(rt);}
}
int calc(int d,int u){int res=0;for(R int i=Head[u];i;i=E[i].nx)if(d>=E[i].d)res+=E[i].c[min(d-E[i].d,E[i].sz)]*E[i].sgn;return n-res;
}
int main(){
// freopen("testdata.in","r",stdin);n=read();fp(i,1,n)a[i]=read();for(R int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);mx[0]=n+1,rt=0,size=n,findrt(1,0),solve(rt);int l,r,mid,ans;fp(i,1,n){l=0,r=n-1;while(l<=r)mid=(l+r)>>1,(calc(mid,i)>=a[i])?(ans=mid,l=mid+1):r=mid-1;print(ans);}return Ot(),0;
}