博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「csp-s模拟测试(9.18)」Set·Read·Race
阅读量:5337 次
发布时间:2019-06-15

本文共 5299 字,大约阅读时间需要 17 分钟。

昨天考试考得有点迷???

一看内存限制,T1 64MB T2 16MB 当场懵比.........

T1 set

考场打的背包问题和随机化,其实能randA掉,但不小心数组开小了????(长记性!!!!!

正解的话因为每个前缀只需mod%n,所以有n+1个数,其中一定有重复的

所以就可以O(n)扫了

其实正解不难就是没有细想

1 #include
2 #define MAXN 1100 3 using namespace std; 4 int read(){ 5 int x=0;char c=getchar(); 6 while(c<'0'||c>'9')c=getchar(); 7 while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();} 8 return x; 9 }10 int n;11 int a[MAXN*MAXN];12 struct node{
int id,w;}e[1000001];13 int ans[MAXN];14 int pre[MAXN][1001];15 bool biao[2][MAXN];16 void work(){17 for(int i=1;i<=n;++i){18 e[i].id=i;e[i].w=a[i];19 }20 for(int i=1;i<=20000;++i){21 if(clock()>990000){22 printf("-1\n");23 return ;24 }25 random_shuffle(e+1,e+n+1);26 int ok=0;int me=0;27 for(int j=1;j<=n;++j){28 me=(me+(e[j].w%n))%n;29 if(me==0){30 ok=j;break;31 }32 }33 if(ok==0)continue;34 printf("%d\n",ok);35 for(int j=1;j<=ok;++j)printf("%d ",e[j].id);36 return ;37 }38 }39 signed main(){40 n=read();41 for(int i=1;i<=n;++i){42 a[i]=read();a[i]%=n;43 }44 if(n>1000){45 work();46 return 0;47 }48 int now=1;int last=0;49 biao[last][0]=1;50 for(int i=1;i<=n;++i){51 for(int j=0;j
=1;--i){68 if(pre[i][now]!=0)ans[++ans[0]]=pre[i][now];69 now=(now-a[pre[i][now]]%n+n)%n; 70 }71 if(ans[0]==0){printf("-1\n");return 0;}72 printf("%d\n",ans[0]);73 for(int i=1;i<=ans[0];++i){74 printf("%d ",ans[i]);75 }76 cout<
考场随机化暴力
1 #include
2 #define MAXN 1100000 3 #define int long long 4 using namespace std; 5 int vis[MAXN];int n,a[MAXN]; 6 signed main(){ 7 scanf("%lld",&n); 8 vis[0]=0; 9 for(int i=1;i<=n;++i){10 scanf("%lld",&a[i]);11 }int sum=0;12 for(int i=1;i<=n;++i){13 sum=(a[i]+sum)%n;14 if(vis[sum]!=0){15 printf("%lld\n",i-vis[sum]);16 for(int j=vis[sum]+1;j<=i;++j){17 printf("%lld ",j);18 }19 return 0;20 }21 vis[sum]=i;22 }23 }
View Code

 

T2 read

考场时看出了答案其实就是2*maxn_sum-N-1,至于证明,除非最后时只剩一种类型的书了,不然肯定能接着放

那么我们就可以直接判断了

考场没算清内存其实1e6的数据是可以开数组的

对于正解,定义一个id,cnt

我们对于每个新出现的数,当cnt=0时id=当前数,不然id=当前数cnt++;否则cnt--;

可以发现如果存在解的话,id一定为最大出现次数的值,但是因为可能中间存在非最大值之间互相抵消的情况

所以还要再扫一边,判断当前值出现次数

1 #include
2 #define MAXN 1100 3 #define int long long 4 using namespace std; 5 int M,N,K; 6 int co[MAXN],x[MAXN],y[MAXN],z[MAXN];int a[MAXN]; 7 int maxn_sum=0;int maxn;int S; 8 signed main(){ 9 scanf("%lld%lld",&M,&K);10 S=(1<
0){printf("%lld\n",2*cnt-N-1);}43 else printf("0\n");44 /*scanf("%lld",&N);45 int cnt=0;int id=0;46 for(int i=1;i<=N;++i){scanf("%lld",&a[i]);}47 for(int i=1;i<=N;++i){48 long long last=a[i]; 49 if(cnt==0){cnt=1;id=last;}50 else if(id==last){cnt++;}51 else if(id!=last){cnt--;} printf("i=%lld\n",i); 52 }53 if(cnt-1>0)printf("%lld\n",cnt-1);54 else printf("%lld\n",cnt);55 */56 }57 /*58 2259 1 3 3 3 3 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 60 */
View Code

 

T3 race

咕了.............

不咕。

一道trie树好题,想了两节课,(在语文课上想题效率很高QAQ)

首先对于x^2的转化:

   既然是排名,我们可以考虑成x^2,是每个大于他的数的集合相乘,即(x1+x2+x3+x4.....)*(x1+x2.......)

(其中每个xi都为1),那么结果可以看成任意一个点对的贡献为一,答案就是点对的个数

既然结果是求异或和,我们联想到trie树(这样说有些牵强.......)

无论如何我们先建棵trie树

那么从1-n的每个i,我们统计这个节点时单独考虑每一位的贡献,我们枚举一个j,一个k

j(k)上的数表示在M-1位到j+1位的数与a[i]的这些位的数相等,那么如果使j,k同时大于a[i],我们只需

确定好异或的第j,k位上的数,其他数随意,这样这两位上的数对他的贡献就是两个位的指针上的size*(1<<M-2)

当j==k时乘的变成(1<<M-1),因为只需确定一位

 

1 #include
2 #define int long long 3 #define MAXN 210000 4 using namespace std; 5 int fa[MAXN][31]; 6 struct node{ 7 int ch[2]; 8 int size; 9 }t[MAXN*20];int n,M;10 const int mod=1e9+7;11 int tot=1;int a[MAXN];12 void insert(int x){13 int p=1;t[p].size++;fa[x][M]=1;14 for(int i=M-1;i>=0;--i){15 int me=(a[x]>>i)&1;16 if(t[p].ch[me]==0)t[p].ch[me]=++tot;17 p=t[p].ch[me];18 t[p].size++;19 fa[x][i]=p;20 }21 }22 int ans[MAXN];23 void work(int x){24 for(int i=0;i<=M-1;++i){25 int me1=0,find1=0;int me2=0,find2=0;26 for(int j=0;j
>i)&1;me2=(a[x]>>j)&1;28 me1^=1;me2^=1;29 find1=fa[x][i+1];find2=fa[x][j+1];30 ans[x]=(ans[x]+2*t[t[find1].ch[me1]].size*t[t[find2].ch[me2]].size%mod*(1ll<<(M-2ll)))%mod;31 }32 me1=(a[x]>>i)&1;me1^=1;33 find1=fa[x][i+1];34 ans[x]=(ans[x]+t[t[find1].ch[me1]].size*t[t[find1].ch[me1]].size%mod*(1<<(M-1)))%mod;35 }36 }37 int sum=0;38 signed main(){39 scanf("%lld%lld",&n,&M);40 for(int i=1;i<=n;++i){41 scanf("%lld",&a[i]);42 }43 for(int i=1;i<=n;++i){insert(i);}44 for(int i=1;i<=n;++i){work(i);}45 for(int i=1;i<=n;++i){46 sum^=ans[i];47 }48 printf("%lld\n",sum);49 }
View Code

 

 

 

******************************

思路积累:

x^2的转化,

trie树的应用,

比较大小只需考虑每一位的贡献

 

转载于:https://www.cnblogs.com/Wwb123/p/11548363.html

你可能感兴趣的文章
python使用cx_Oracle连接oracle
查看>>
【排序】
查看>>
CSS 基础 例子 水平 & 垂直对齐
查看>>
解决tomcat 启动 一闪而过
查看>>
c++泛型模板
查看>>
弱者归来
查看>>
js的兼容性问题
查看>>
LeetCode Intersection of Two Arrays II
查看>>
6-9 Haar+adaboost人脸识别
查看>>
Android View学习示例
查看>>
multiprocessing进程开发RuntimeError
查看>>
团队站立会议02
查看>>
“华为杯”山东理工大学第十一届ACM程序设计竞赛 E - 九连环
查看>>
上帝永远不会问你的十件事
查看>>
oracle 学习笔记(四)
查看>>
管理平台页面开发注意事项
查看>>
Lazarus下改变DBGrid记录的颜色,与Delphi不同了。
查看>>
有关easyui-layout的收缩层无标题的解决办法
查看>>
再也不必当心我的密码了,多个SAP 客户端自动输入密码
查看>>
SAP ECC CO 配置
查看>>