16 hrbust邀请赛D、F题解
来源:互联网 发布:中国网络电视台体育台 编辑:程序博客网 时间:2024/05/16 17:11
周末打了个kuangbin聚聚出的网络邀请赛,水了7个题,旗神来写了一个,rk16滚粗。
其实说是写了7个题,但是5个sb题,1个模板题,1个找规律题,后面的题都没怎么看,据说有一个网络流还有两个神题?所以我这这场干了啥。。。
D是给了1e5个1e5以内的数,然后给1e5个询问k,k是2e5,问有多少个pair(i,j),满足ai+aj小于k。
一边吃饭一边看了约20min,发现就是个裸的FFT|NTT,卷积一下求个前缀和,然后把自己匹配的减掉就好了。于是愉快地拍(copy&paste)了一个强无敌的NTT板子,xjb调调就过了。
板子如下:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 262144const long long P=50000000001507329LL; // 190734863287 * 2 ^ 18 + 1//const int P=1004535809; // 479 * 2 ^ 21 + 1//const int P=998244353; // 119 * 2 ^ 23 + 1const int G=3;long long mul(long long x,long long y){ return (x*y-(long long)(x/(long double)P*y+1e-3)*P+P)%P;}long long qpow(long long x,long long k,long long p){ long long ret=1; while(k) { if(k&1) ret=mul(ret,x); k>>=1; x=mul(x,x); } return ret;}long long wn[25];void getwn(){ for(int i=1; i<=18; ++i) { int t=1<<i; wn[i]=qpow(G,(P-1)/t,P); }}int len;void NTT(long long y[],int op){ for(int i=1,j=len>>1,k; i<len-1; ++i) { if(i<j) swap(y[i],y[j]); k=len>>1; while(j>=k) { j-=k; k>>=1; } if(j<k) j+=k; } int id=0; for(int h=2; h<=len; h<<=1) { ++id; for(int i=0; i<len; i+=h) { long long w=1; for(int j=i; j<i+(h>>1); ++j) { long long u=y[j],t=mul(y[j+h/2],w); y[j]=u+t; if(y[j]>=P) y[j]-=P; y[j+h/2]=u-t+P; if(y[j+h/2]>=P) y[j+h/2]-=P; w=mul(w,wn[id]); } } } if(op==-1) { for(int i=1; i<len/2; ++i) swap(y[i],y[len-i]); long long inv=qpow(len,P-2,P); for(int i=0; i<len; ++i) y[i]=mul(y[i],inv); }}void Convolution(long long A[],long long B[],int len1,int len2){ int n=max(len1,len2); for(len=1; len<(n<<1); len<<=1); for(int i=len1; i<len; ++i) { A[i]=0; } for (int i=len2;i<len;i++) { B[i]=0; } NTT(A,1); NTT(B,1); for(int i=0; i<len; ++i) { A[i]=mul(A[i],B[i]); } NTT(A,-1);}long long A[MAXN],B[MAXN];long long sum[MAXN<<1];long long sum2[MAXN];int main(){ getwn(); int t; scanf("%d", &t); while(t--) { memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B)); int n, m; scanf("%d%d", &n, &m); int M=0; for(int i=1;i<=n;i++){ int tmp; scanf("%d", &tmp); A[tmp]++; B[tmp]++; M=max(M, tmp); } sum2[0]=B[0]; for(int i=1;i<=M+1;i++)sum2[i]=sum2[i-1]+B[i]; Convolution(A,B,M+1,M+1); sum[0]=A[0]; for(int i=1;i<=2*M+2;i++)sum[i]=sum[i-1]+A[i]; for(int i=1;i<=m;i++){ int k; scanf("%d", &k); if(k>2*M+1)k=2*M+1; printf("%lld\n", (sum[k-1]-sum2[(k-1)/2])/2); } } return 0;}
然后F在旗神的打表下,发现fib数列偏移值是6为循环节,大概是0 -1 0 1 0 1,然后发现转移矩阵搞个循环队列就ok了,于是结束前30min水过,挂机结束。
水过代码:
#include <cstdio>#include <cstring>using namespace std;typedef long long ll;const int mod=1e9+7;struct mat{ ll a[8][8];};mat mult(mat a, mat b){ mat ans; for(int i=0;i<8;i++) for(int j=0;j<8;j++){ ans.a[i][j]=0; for(int k=0;k<8;k++) ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod; } return ans;}mat power(ll n){ mat ans; for(int i=0;i<8;i++) for(int j=0;j<8;j++)ans.a[i][j]=(i==j); mat base; memset(base.a, 0, sizeof(base.a)); base.a[0][0]=base.a [0][1]=base.a[0][2]=base.a[1][0]=base.a[2][3]=base.a[3][4]=base.a[4][5]=base.a[5][6]=base.a[6][7]=base.a[7][2]=1; while(n){ if(n&1){ ans=mult(ans, base); } base=mult(base, base); n>>=1; } return ans;}int main(){ ll n; while(~scanf("%lld", &n)){ if(!n){ printf("7\n"); continue; } mat ans=power(n-1); ll aa=(ans.a[0][0]*11+ans.a[0][1]*7-ans.a[0][3]+ans.a[0][5]+ans.a[0][7]+mod)%mod; printf("%lld\n", aa); }}
挂机之后就愉快地玩耍去了。
0 0
- 16 hrbust邀请赛D、F题解
- 2017 ICPCECPC 邀请赛 F,D,E, I 题解
- C,D,F,G,H题 题解
- 南京邀请赛f
- hrbust 1990 函数F(x)
- 地大邀请赛d
- d/ F
- 2014北京邀请赛(部分题解)
- 2014 北京邀请赛ABDHJ题解
- 2013 通化邀请赛ABCDEGHIJ题解
- 2014西安邀请赛部分题解
- 2013 长沙邀请赛 ADEGH 题解
- 2013通化邀请赛部分题解
- 2014西安邀请赛部分题解
- 2015上海大都会邀请赛 题解
- POJ 4049 金华赛区邀请赛F题
- 2014北京邀请赛 F Football on Table
- 2014 BNU邀请赛F题(枚举)
- TCP_server
- AndroidStudio中的java文件莫名奇妙全部飙红
- POJ 2718 Smallest Difference 已被翻译
- Multiple annotations found at this line——已解决
- MySQL函数学习
- 16 hrbust邀请赛D、F题解
- HBase伪分布式环境搭建及命令行使用
- mysql5.7新特性
- BIOS 扩展 INT 13
- poj1008 模拟
- 性能优化之电量优化3-优化方案
- IoC容器笔记1
- leetcode--remove_cuplicates_rfom_sorted_array
- kali