目录
A | B | C | D | E | F |
---|---|---|---|---|---|
√ | √ | √ | √ | ○ | ○ |
( √:做出; ●:尝试未做出; ○:已补题 )
题目地址:https://atcoder.jp/contests/aising2020
A Number of Multiples
题意:签到题
思路:
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1;
char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
int main()
{
int L=read(),R=read(),d=read();
int ans=0;
REP(i,L,R) if(i%d==0) ans++;
cout<<ans;
return 0;
}
B An Odd Problem
题意:签到题
思路:
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1;
char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
int main()
{
int ans=0,n=read();
REP(i,1,n)
{
int x=read();
if(i&1 && x&1) ans++;
}
cout<<ans;
return 0;
}
C XYZ Triplets
题意: 表示满足以下条件的三元组 的个数:
给出 N( ),输出 。
思路:根据 N 的范围可以推断出,xyz都不超过100,所以就三重循环更新 f 数组就行了。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1;
char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
int f[10005];
int main()
{
REP(i,1,100) REP(j,1,100) REP(k,1,100)
{
int x=i*i+j*j+k*k+i*j+i*k+j*k;
if(x<=10000) f[x]++;
}
int N=read();
REP(i,1,N) printf("%d\n",f[i]);
return 0;
}
D Anything Goes to Zero
题意: 表示把一个非负整数 n 经过若干次这样的操作——把 n 替换成 ——最后变成 0 所需要操作的次数。现在给出有 N( ) 位的二进制数 X,对于每一位 ,定义 为把 X 的第 i 位反转变成的二进制数,求出 。
思路:对于每一个 ,如果我们计算完第一步,也就是经过了一次操作之后,得到的结果一定不超过 N,因为一开始的 X 的 1 的个数不会超过 N,然后之后的操作就可以很快的完成。所以最重要的是如何尽快的把每一个 的第一步计算出来。设原来的 X 有 m 个 1,那么对于每个 ,1 的个数要么是 m-1,要么是 m+1,所以我们只需要求出 X 对 m-1 和 m+1 的模,并且求出每一个 2 的幂对 m-1 和 m+1 的模,然后对于每一个 ,只需要在 X 的答案的基础上减去或者加上相应的 2 的幂的答案就行了。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1;
char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=2e5+5;
int a[maxn],M=0,n,f[maxn],ff[maxn];
LL tot,tott;
char s[maxn];
int get(int x)
{
int ret=0;
while(x)
{
ret++;
x%=__builtin_popcount(x);
}
return ret;
}
int main()
{
n=read();
scanf("%s",s+1);
REP(i,1,n) a[i]=s[i]-'0',M+=a[i];
if(M==0) {REP(i,1,n) puts("1"); return 0;}
if(M==1)
{
if(a[n]==1)
{
REP(i,1,n-1) puts("2");
puts("0");
return 0;
}
else
{
REP(i,1,n-1) puts(a[i]?"0":"1");
puts("2");
return 0;
}
}
f[0]=1%(M-1); ff[0]=1%(M+1);
REP(i,1,n) f[i]=f[i-1]*2%(M-1),ff[i]=ff[i-1]*2%(M+1);
REP(i,1,n) if(a[i]) tot+=f[n-i],tott+=ff[n-i];
REP(i,1,n)
{
int x;
if(a[i]) x=(tot-f[n-i])%(M-1);
else x=(tott+ff[n-i])%(M+1);
printf("%d\n",1+get(x));
}
return 0;
}
E Camel Train
题意:有 n 只骆驼。对于第 i 只骆驼,给出三个正整数 ,表示如果把这只骆驼放在前 的位置,就会有收益 ,否则会有收益 。问最大收益。
思路:我们可以把骆驼分为两组: 的(1组)和 的(2组)。这样 1组的骆驼一定全部在 2组骆驼的左边,否则交换相应骆驼也不会使得总收益变少。我们如果满足第 i 只骆驼(这里满足的意思是指按照其 L 和 R 的大小关系给它分配收益更大的位置),实际上获得的可以跟其它骆驼比较的收益是 。也就是说,对于每只骆驼我们都可以看成有一个基础收益 ,然后我们要尽量满足 更大的骆驼。这里就对两组骆驼分别用优先队列去维护符合要求的 即可。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=2e5+5;
struct node
{
int L,R,K;
bool operator < (const node x) const {return K<x.K;}
}a[maxn];
int main()
{
int T=read();
while(T--)
{
int n=read();
REP(i,1,n) a[i].K=read(),a[i].L=read(),a[i].R=read();
vector<node> x,y;
REP(i,1,n)
if(a[i].L>=a[i].R) x.pb(a[i]);
else y.pb(a[i]);
sort(x.begin(),x.end()); sort(y.begin(),y.end());
LL ans=0;
REP(i,1,n) ans+=min(a[i].L,a[i].R);
priority_queue<int,VI,greater<int> > Q;
REP(i,1,x.size())
{
int add=abs(x[i-1].L-x[i-1].R),k=x[i-1].K;
if(k>Q.size()) Q.push(add);
else if(!Q.empty() && add>Q.top()) Q.pop(),Q.push(add);
}
while(!Q.empty()) ans+=Q.top(),Q.pop();
REP(i,1,y.size())
{
int add=abs(y[y.size()-i].L-y[y.size()-i].R),k=n-y[y.size()-i].K;
if(k>Q.size()) Q.push(add);
else if(!Q.empty() && add>Q.top()) Q.pop(),Q.push(add);
}
while(!Q.empty()) ans+=Q.top(),Q.pop();
printf("%lld\n",ans);
}
return 0;
}
F Two Snuke
题意:给定一个正整数 N( ),要求凑出十个非负整数 ,并且满足: (其它四组一样),且 。对于每一个可行的方案,都会对答案产生 这么多贡献。要求求出总贡献。多组数据。
思路:正解好像是用插值法。但是似乎它的答案是一个线性递推式,所以可以暴力算出前 40 项左右,打表,然后用 BM 算法就过了。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include <bits/stdc++.h>
#include <cstdio>
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<LL,LL> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=40005;
const LL M=1e9+7;
struct linear_sequence
{
LL res[maxn],base[maxn],_c[maxn],_md[maxn];
VI Md;
LL ksm(LL x,LL n)
{
LL ret=1;
while(n)
{
if(n&1) ret=ret*x%M;
x=x*x%M;
n>>=1;
}
return ret;
}
void multi(LL *a,LL *b,int k)
{
REP(i,0,(k<<1)-1) _c[i]=0;
REP(i,0,k-1) if(a[i]) REP(j,0,k-1)
_c[i+j]=(_c[i+j]+a[i]*b[j])%M;
REP_(i,k+k-1,k) if(_c[i]) REP(j,0,Md.size()-1)
_c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%M;
REP(i,0,k-1) a[i]=_c[i];
}
int solve(LL n,VI a,VI b)
{
LL ans=0,pnt=0;
int k=a.size();
//assert(a.size()==b.size());
REP(i,0,k-1) _md[k-1-i]=-a[i];
_md[k]=1;
Md.clear();
REP(i,0,k-1) if(_md[i]) Md.pb(i);
REP(i,0,k-1) res[i]=base[i]=0;
res[0]=1;
while((1ll<<pnt)<=n) pnt++;
REP_(p,pnt,0)
{
multi(res,res,k);
if((n>>p)&1)
{
REP_(i,k-1,0) res[i+1]=res[i];
res[0]=0;
REP(j,0,Md.size()-1) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%M;
}
}
REP(i,0,k-1) ans=(ans+res[i]*b[i])%M;
return (ans+M)%M;
}
VI BM(VI s)
{
VI C(1,1),B(1,1);
int L=0,m=1,b=1;
REP(n,0,s.size()-1)
{
LL d=0;
REP(i,0,L) d=(d+(LL)C[i]*s[n-i])%M;
if(!d) ++m;
else if((L<<1)<=n)
{
VI T=C;
LL c=M-d*ksm(b,M-2)%M;
while(C.size()<B.size()+m) C.pb(0);
REP(i,0,B.size()-1) C[i+m]=(C[i+m]+c*B[i])%M;
L=n+1-L,B=T,b=d,m=1;
}
else
{
LL c=M-d*ksm(b,M-2)%M;
while(C.size()<B.size()+m) C.pb(0);
REP(i,0,B.size()-1) C[i+m]=(C[i+m]+c*B[i])%M;
++m;
}
}
return C;
}
int get(VI a,LL n)
{
VI c=BM(a);
c.erase(c.begin());
REP(i,0,c.size()-1) c[i]=(M-c[i])%M;
//for(int i:c) printf("%d ",i);
//puts("");
return solve(n,c,VI(a.begin(),a.begin()+c.size()));
}
}ls;
int cal(int n)
{
LL ret=0;
REP(s1,0,n-4) REP(s2,s1+1,n-4) if(s1+s2<=n-4)
REP(n1,0,n-4) REP(n2,n1+1,n-4) if(s1+s2+n1+n2<=n-3)
REP(u1,0,n-4) REP(u2,u1+1,n-4) if(s1+s2+n1+n2+u1+u2<=n-2)
REP(k1,0,n-4) REP(k2,k1+1,n-4) if(s1+s2+n1+n2+u1+u2+k1+k2<=n-1)
REP(e1,0,n-4) REP(e2,e1+1,n-4)
{
int tot=s1+s2+n1+n2+u1+u2+k1+k2+e1+e2;
if(tot>n) continue;
ret+=1ll*(s2-s1)*(n2-n1)*(u2-u1)*(k2-k1)*(e2-e1);
}
return ret%M;
}
int f[]={
0,
0,
0,
0,
1,
11,
71,
341,
1346,
4598,
14038,
39138,
101193,
245443,
563447,
1232837,
2585672,
5222552,
10198232,
19316488,
35588718,
63933498,
112225058,
192839398,
324900532,
537499132,
874246012,
399637805,
207858088,
434820093,
274485959,
780358,
996765147,
793168065,
118878018,
966647141,
677996797,
52230779,
485540255,
147468710,
203524158,
94513877,
885277100,
};
int main()
{
VI x;
/*
REP(i,1,50)
{
cout<<cal(i)<<','<<endl;
//x.pb(cal(i));
}
*/
for(int i:f) x.pb(i);
int T=read();
while(T--)
{
int n=read();
printf("%d\n",ls.get(x,n-1));
}
return 0;
}