您的位置:首页 > 移动开发 > 微信开发

UOJ#267 BZOJ4731【清华集训2016】魔法小程序

2017-03-04 17:47 423 查看
UOJ终于把清华集训的题加上辣!BZOJ上数据还是错的,之前写完代码都没地方交

题意就是让你做任意进制的FWT的逆变换

类比二进制容易得到在k进制下的做法:把整个序列分成k段,分别递归处理剩余位的影响后考虑这一位的影响即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 1000010
#define MAXM 1000010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
int n,m;
int M=1;
int a[MAXN];
ll c[MAXN];
ll len[MAXN];
int tot;
int L[MAXN],R[MAXN];
int ta[MAXN];
void cal(int l,int r,int d){
int i,j;
if(!d){
return ;
}
int t=0;
int lst=l;
for(i=l;i<=r;i++){
t++;
if(t==len[d-1]||i==r){
cal(lst,i,d-1);
lst=i+1;
t=0;
}
}
t=0;
lst=l;
tot=0;
for(i=l;i<=r;i++){
t++;
if(t==len[d-1]||i==r){
tot++;
L[tot]=lst;
R[tot]=i;
lst=i+1;
t=0;
}
}
for(i=tot;i>1;i--){
for(j=L[i];j<=R[i];j++){
c[j]-=c[j-len[d-1]];
}
}
}
int main(int argc,char *argv[]){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int tn=0;
for(i=1;i<=n;i++){
if(a[i]!=1){
ta[++tn]=a[i];
}
}
scanf("%d",&m);
ta[tn+1]=m;
for(i=1;i<=m;i++){
scanf("%lld",&c[i]);
}
len[0]=1;
for(i=1;i<=tn+1;i++){
len[i]=len[i-1]*ta[i];
if(len[i]>=m){
cal(1,m,i);
break;
}
}
printf("%d\n",n);
for(i=1;i<=n;i++){
printf(i==n?"%d\n":"%d ",a[i]);
}
printf("%d\n",m);
for(i=1;i<=m;i++){
printf(i==m?"%lld\n":"%lld ",c[i]);
}
return 0;
}

/*

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: