Codeforces Round #737 (Div. 2)
A
刚开始其实并不会然后看了看样例发现自己会了。
大概就是把最大的拿出来然后剩下的放一起,正确性易证。
code:
using namespace std;
int T,n,x;ll Maxn,ToT;
int main(){
scanf("%d",&T);while(T--){
scanf("%d",&n);Maxn=-1e18;ToT=0;for(int i=1;i<=n;i++)scanf("%d",&x),Maxn=max(Maxn,x),ToT+=x;printf("%.8lf\n",Maxn+(ToT-Maxn)*1.0/(n-1));
}
}
B
被假做法卡了半天。
排好序的序列是固定的所以可以算出来,然后对应原序列的位置也可以算出来。
然后看连续段就好了。
code:
int T,n,A[N+5],Ans,k,Id[N+5];I bool cmp(int x,int y){return A[x]<A[y];}
int main(){
freopen("1.in","r",stdin);
re int i,j;scanf("%d",&T);while(T--){
Ans=0;scanf("%d%d",&n,&k);for(i=1;i<=n;i++)scanf("%d",&A[i]),Id[i]=i;sort(Id+1,Id+n+1,cmp);for(i=2;i<=n;i++) Ans+=(Id[i]!=Id[i-1]+1);printf("%s\n",Ans+1<=k?"YES":"NO");
}
}
C
这个C比D难好吧尽管都很板子。
因为位运算的性质所以我们肯定枚举一位不同,然后高位相同低位随意。
低位随意随便搞搞,高位相同我们设\(F(x,n)\)表示\(x\)位\(n\)个数满足题面式子相等的答案。
如果我们设\(G(x,n)\)为\(x\)位\(n\)个数异或出来和与出来都是\(0\)的方案数,那么\(G(x)=2^{n(x-1)}\)
然后\(F(x)=\sum\limits_{i=0}^{x}{C_{x}^{i}G(x-i)}\)然后二项式定理一下就好了。
code:
using namespace std;
int n,m,k,T,x,y,z;ll B[N+5][2],Ans,now;
I ll mpow(ll x,int y=mod-2){ll Ans=1;while(y) y&1&&(Ans=Ans*x%mod),y>>=1,x=x*x%mod;return Ans;}
I ll calc(int x,int y){now=mpow(2,x-1)-(n%2==0)*2+mod;return mpow(now+1,y);}
int main(){
freopen("1.in","r",stdin);
re int i;scanf("%d",&T);while(T--){
Ans=0;scanf("%d%d",&n,&k);if(n%2==0){
for(i=k-1;~i;i--) Ans+=calc(n,k-i-1)*mpow(mpow(2,n),i)%mod;
}Ans+=calc(n,k);printf("%lld\n",Ans%mod);
}
}
D
设\(dp_i\)为到\(i\)行最多能保留的行数。
然后肯定是离散以后找一个有一列相同的最大转移,然后这个放在线段树上转移就好了。
code:
using namespace std;
int n,m,k,x[N+5],y[N+5],z[N+5],dp[N+5],nows[N+5<<1],tots[N+5<<1],las[N+5],Fl[N+5],ToT;
struct Ques{int x,y;};vector<Ques> G[N+5];
struct pai{int w,id;pai operator +(const pai &B)const{return w>B.w?(pai){w,id}:B;};}F[N+5<<4],Sum[N+5<<4],Cl,now;
I void pushF(int now,pai z){F[now]=F[now]+z;Sum[now]=Sum[now]+z;}I void push(int x){pushF(x<<1,F[x]);pushF(x<<1|1,F[x]);F[x]=Cl;}I void Up(int now){Sum[now]=Sum[now<<1]+Sum[now<<1|1];}
I void insert(int x,int y,pai z,int l=1,int r=2*m,int now=1){
if(x<=l&&r<=y) return pushF(now,z);push(now);int m=l+r>>1;x<=m&&(insert(x,y,z,l,m,now<<1),0);y>m&&(insert(x,y,z,m+1,r,now<<1|1),0);Up(now);
}
I pai find(int x,int y,int l=1,int r=m*2,int now=1){
if(x<=l&&r<=y) return Sum[now];push(now);int m=l+r>>1;pai Ans=Cl;x<=m&&(Ans=Ans+find(x,y,l,m,now<<1),0);y>m&&(Ans=Ans+find(x,y,m+1,r,now<<1|1),0);return Ans;
}
int main(){
freopen("1.in","r",stdin);
re int i,j;scanf("%d%d",&n,&m);for(i=1;i<=m;i++) scanf("%d%d%d",&z[i],&x[i],&y[i]),nows[i*2-1]=x[i],nows[i*2]=y[i];sort(nows+1,nows+m*2+1);for(i=1;i<=m*2;i++) tots[i]=tots[i-1]+(nows[i]!=nows[i-1]);
for(i=1;i<=m;i++)x[i]=tots[lower_bound(nows+1,nows+2*m+1,x[i])-nows],y[i]=tots[lower_bound(nows+1,nows+2*m+1,y[i])-nows],G[z[i]].push_back((Ques){x[i],y[i]});
for(i=1;i<=n;i++){
now=Cl;for(j=0;j<G[i].size();j++) now=now+find(G[i][j].x,G[i][j].y);dp[i]=now.w+1;las[i]=now.id;dp[i]>dp[ToT]&&(ToT=i);for(j=0;j<G[i].size();j++) insert(G[i][j].x,G[i][j].y,(pai){dp[i],i});
}printf("%d\n",n-dp[ToT]);while(ToT) Fl[ToT]=1,ToT=las[ToT];for(i=1;i<=n;i++) !Fl[i]&&(printf("%d ",i));
}
E
考虑一种方法,如果king和queen的行和列之差都为奇数,那么queen可以先确定左上,右上,左下,右下一个方向,并且按照king的方案不改变奇偶性地夹过去,一直夹到边为之,
这个是要\(32\)次询问的。
然后分别改变行和列的奇偶性就可以得到一个\(32*4+3\)的做法,然而并不能被卡掉。
code:
using namespace std;
int T,n,m,k,flag,x,y,z,nowx,nowy,Fl;string a,B[N+5]={"Right", "Left", "Up", "Down", "Down-Right", "Down-Left", "Up-Left", "Up-Right","Done"};
I int Y(string a){return (a==B[0])||(a==B[1])||(a==B[4])||(a==B[5])||(a==B[6])||(a==B[7]);}
I int X(string a){return (a==B[2])||(a==B[3])||(a==B[4])||(a==B[5])||(a==B[6])||(a==B[7]);}
I void Over(string a){if(a==B[8])Fl=1;}
I void Out(){cout<<nowx<<" "<<nowy<<endl;}
I void push(){
flag=0;while(!flag){
cin>>a;Over(a);if(Fl) return;if(X(a)){
if(nowx==8) {nowx--;flag=1;}else nowx++;
}
if(Y(a)){
if(nowy==8) {nowy--;flag=1;}else nowy++;
}Out();
}
flag=0;while(!flag){
cin>>a;Over(a);if(Fl) return;if(X(a)){
if(nowx==1) {nowx++;flag=1;}else nowx--;
}
if(Y(a)){
if(nowy==8) {nowy--;flag=1;}else nowy++;
}Out();
}
flag=0;while(!flag){
cin>>a;Over(a);if(Fl) return;if(X(a)){
if(nowx==1) {nowx++;flag=1;}else nowx--;
}
if(Y(a)){
if(nowy==1) {nowy++;flag=1;}else nowy--;
}Out();
}
flag=0;while(!flag){
cin>>a;Over(a);if(Fl) return;if(X(a)){
if(nowx==8) {nowx--;flag=1;}else nowx++;
}
if(Y(a)){
if(nowy==1) {nowy++;flag=1;}else nowy--;
}Out();
}
}
int main(){
scanf("%d",&T);while(T--){
Fl=0;printf("%d %d\n",nowx=4,nowy=4);fflush(stdout);
push();if(Fl) continue;cin>>a;Over(a);if(Fl) continue;if(!X(a)) {if(nowx==8)nowx--;else nowx++;}if(Y(a)){if(nowy==8) nowy--;else nowy++;}if(X(a)&&!Y(a)){if(nowx>=7) nowx-=2;else nowx+=2;}Out();
push();if(Fl) continue;cin>>a;Over(a);if(Fl) continue;if(X(a)) {if(nowx==8)nowx--;else nowx++;}if(!Y(a)){if(nowy==8) nowy--;else nowy++;}if(!X(a)&&Y(a)){if(nowx>=7) nowx-=2;else nowx+=2;}Out();
push();if(Fl) continue;cin>>a;Over(a);if(Fl) continue;if(!X(a)) {if(nowx==8)nowx--;else nowx++;}if(Y(a)){if(nowy==8) nowy--;else nowy++;}if(X(a)&&!Y(a)){if(nowx>=7) nowx-=2;else nowx+=2;}Out();push();if(Fl) continue;
}
}