Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死
以后一定打对拍,要不考后会。。。
T1 石子游戏
首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则先手必输
那么这道题给出了取石子上限,那么每堆石子$\mod x+1$然后异或就可以知道谁必胜了
然后这道题就转化为如何求$\sum \limits_{i=1}^{n}\oplus a_i \mod(x+1)$。
分段考虑每一段$[k(x+1),(k+1)(x+1)]$,然后预处理一个$f$数组
$UPD 2021.10.7$然而$A$掉这道题后发现并不是跟题解说的那样简单。
关于数组$f$:
题解里面预处理的$f$数组是基于位运算的,$f[i][j]$是由第$j+1$位加一个$1$转移过来的,
然后这一段区间使用了状压的思想枚举了子集算出的和累加的贡献,把后面的式子拆开就可以发现,累加的次数刚好为$[0,2^{j}-1]$,
这还表明了一个问题,就是只有偶数段才会做贡献。别着急问偶数段是啥,先听我说
刚才说累加的次数只有$2^j$次,而$2^{j+1}=2^{j} \times 2$是累加次数的二倍,再看累加的起点终点,
不难发现,如果把$2^j$长度称为一段,那么$2^{j+1}$就是两段,分开考虑这两段。
因为累加的起点在第二段开头也就是$i+2^j$而不是$i$,所以每次加上一个$2^{j+1}$长度的区间里面都只有第二段做出了累加的贡献
所以说只有偶数段才做贡献。
关于答案计算:
理解透彻$f$的转移方式之后便可以计算答案了。
对于枚举每一个$x+1$,我们枚举一个$j$,显然只会枚举到$log_2(x)$,然后我们再枚举一下可能的$k$
找到一段要计算的区间$[l,r]$,使用向下取整的方式找到距离$r$最近的$l+2^{j+1}$,这一段的贡献可以用预处理出的数组直接做后缀和求出
然后考虑区间$[l+2^{j+1},r]$,这段区间如果是在奇数区间,则不用计算单独的贡献,因为他没有,
如果有一些在偶数区间或者被偶数区间包含,就需要使用前缀和求出贡献,很好求,直接最右端减去最左端就行
算出的这个数如果是奇数,就会有贡献,给计数器上的$j$位异或一个$1$,因为要计算总和,现在枚举的是区间
需要找的是所有可能区间的答案的和是否为奇数,所以是异或,不是与,如果两个区间都是奇数那答案就会变成偶数。
这样就差不多了。
1 #include<bits/stdc++.h>
2 #define int long long
3 #define pw(x) (1<<(x))
4 #define lg(x) (log2(x))
5 using namespace std;
6 namespace AE86{
7 #define out(x) cout<<#x<<":"<<x<<endl
8 #define fuck cout<<"fuck"<<endl
9 inline int read(){
10 int x=0,f=1;char ch=getchar();
11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
13 }inline void write(int x,char opt='\n'){
14 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
15 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
16 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
17 }using namespace AE86;
18 const int NN=7e5+5;
19 int n,c[NN],f[NN][65];
20 namespace WSN{
21 inline short main(){
22 freopen("stone.in","r",stdin);
23 freopen("stone.out","w",stdout);
24 n=read();
25 for(int i=1;i<=n;i++) ++c[read()];
26 for(int i=1;i<=n;i++) c[i]+=c[i-1];
27 for(int i=n;~i;i--)
28 for(int j=0;j<=lg(n-i+1);j++)
29 f[i][j]=f[min(i+pw(j+1),n)][j]+c[min(i+pw(j+1)-1,n)]-c[i+pw(j)-1];
30 for(int y=2;y<=n+1;y++){
31 int tmp=0; bool flag=0;
32 for(int j=0;j<=lg(y-1);j++){
33 for(int k=0;k*y<=n;k++){
34 int l=k*y,r=min((k+1)*y-1,n),floor=(r-l+1)>>(j+1); bool lim=(l+floor*pw(j+1)+pw(j)<=r);
35 if((f[l][j]-f[l+floor*pw(j+1)][j]+lim*(c[r]-c[l+floor*pw(j+1)+pw(j)-1]))&1) tmp^=1<<j;
36 }
37 if(tmp){flag=1;break;}
38 }
39 printf(flag?"Alice ":"Bob ");
40 }
41 return 0;
42 }
43 }
44 signed main(){return WSN::main();}
T2 大鱼吃小鱼
直接$multiset$水四十
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=3e5+5;
15 int n,w[NN],q,stk[NN],top;
16 multiset<int> s;
17 #define sit multiset<int>::iterator
18 namespace WSN{
19 inline short main(){
20 // freopen("in.in","r",stdin); freopen("sb.out","w",stdout);
21 freopen("fish.in","r",stdin);
22 freopen("fish.out","w",stdout);
23 n=read();for(int i=1;i<=n;i++) w[i]=read(),s.insert(w[i]);
24 q=read();int tim=0;
25 while(q--){
26 int opt=read();++tim;
27 if(opt==1){
28 int st=read(),k=read(),ans=0,flag=0;
29 if(st>=k){write(0);continue;}
30 top=0;
31 while(s.size()){
32 sit it=s.upper_bound(st-1);
33 if(it!=s.begin()) --it;
34 else {flag=1;break;}
35 st+=*it; s.erase(it); stk[++top]=*it;
36 ++ans;
37 if(st>=k) break;
38 }
39 while(top) s.insert(stk[top--]);
40 if(flag||st<k){puts("-1");continue;}
41 write(ans);
42 }
43 if(opt==2){
44 int v=read();s.insert(v);
45 }
46 if(opt==3){
47 int v=read();s.erase(s.find(v));
48 }
49 }
50 return 0;
51 }
52 }
53 signed main(){return WSN::main();}
TLE40
T3 黑客
考场上没写出来的大水数论题,就是五分钟打了暴力就跑,没考虑正解(暴力分太高)
枚举分数算倍数个数就行
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int mod=1e9+7;
15 int A,B,C,D,ans;
16 inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
17 inline int mo(int x){return x>=mod?x-mod:x;}
18 namespace WSN{
19 inline short main(){
20 freopen("hacker.in","r",stdin);
21 freopen("hacker.out","w",stdout);
22 A=read();B=read();C=read();D=read();
23 for(int i=1;i<=999;i++)
24 for(int j=1;j<=999-i;j++) if(gcd(i,j)==1){
25 int l1=ceil(1.0*A/i),r1=B/i;
26 int l2=ceil(1.0*C/j),r2=D/j;
27 int a=min(r1,r2),b=max(l1,l2);
28 if(a-b+1>0) ans=mo(ans+(i+j)*((a-b+1)%mod)%mod);
29 } write(ans);
30 return 0;
31 }
32 }
33 signed main(){return WSN::main();}
T4 黑客(续)
珍爱生命,远离高精
$m=0$加暴力可以获得$70pts$可是考场上没读明白那个限制条件就只打了$m=0$还打挂了
就爆零了,非常难受,以后还事能重载运算符就重载吧,要不一遍一遍的打太容易错
就是一个普通的数位$dp$套高精度,压位高精度到$17$位刚刚好,如果特判$m=0$会更快
$f[pos][sta]$表示$dp$到前$pos$位数字集合选择状态为$sta$时的方案/总和数。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 namespace AE86{
5 inline int read(){
6 int x=0,f=1;char ch=getchar();
7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
9 }inline void write(int x,char opt='\n'){
10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=1005;
15 int n,m,k,ban[10];
16 namespace TASK{
17 int a[505],b[505],ad[505],c[5],bin[5][1005],d[1005],e[1005];
18 inline void get(int *a,int x){for(;x;x/=10) a[++a[0]]=x%10;}
19 inline void task1(){
20 a[0]=a[1]=1;
21 for(int T=1;T<=n;T++){
22 memset(ad,0,sizeof(ad));
23 for(int i=1;i<=a[0];i++){
24 int tmp=k*a[i];
25 a[i]=tmp%10; ad[i+1]=tmp/10;
26 if(ad[i]) a[i]+=ad[i];
27 if(a[i]>=10) ad[i+1]+=a[i]/10,a[i]%=10;
28 } if(ad[a[0]+1]) a[0]++,a[a[0]]=ad[a[0]];
29 if(T==n-1) memcpy(b,a,sizeof(a));
30 }
31 for(int i=a[0];i;--i) printf("%lld",a[i]);puts("");
32 if(n==1){cout<<k<<endl;return;}
33 int oo=(1+k)*k/2; get(c,oo);
34 for(int i=1;i<=c[0];i++){
35 memset(ad,0,sizeof(ad));
36 for(int j=1;j<=b[0];j++){
37 int tmp=c[i]*b[j];
38 bin[i][j]=tmp%10; ad[j+1]=tmp/10;
39 if(ad[j]) bin[i][j]+=ad[j];
40 if(bin[i][j]>=10) ad[j+1]+=bin[i][j]/10,bin[i][j]%=10;
41 }
42 bin[i][0]=b[0];
43 while(ad[b[0]+1]){
44 bin[i][++bin[i][0]]=ad[b[0]+1]%10;
45 ad[b[0]+1]/=10;
46 }
47 if(i!=1){
48 bin[i][0]+=(i-1);
49 for(int j=bin[i][0];j>=i-1;j--) bin[i][j]=bin[i][j-i+1];
50 for(int j=1;j<=i-1;j++) bin[i][j]=0;
51 }
52 }
53 int maxn=0; memset(ad,0,sizeof(ad));
54 for(int i=1;i<=c[0];i++) maxn=max(maxn,bin[i][0]);
55 for(int i=1;i<=maxn;i++){
56 int tmp=0;
57 for(int j=1;j<=c[0];j++) tmp+=bin[j][i];
58 ad[i+1]=tmp/10; d[i]=tmp%10;
59 if(ad[i]) d[i]+=ad[i];
60 if(d[i]>=10) ad[i+1]+=d[i]/10,d[i]%=10;
61 } d[0]=maxn;
62 while(ad[maxn+1]){
63 d[++d[0]]=ad[maxn+1]%10;
64 ad[maxn+1]/=10;
65 }
66 memcpy(e,d,sizeof(d));
67 for(int i=1;i<n;i++){
68 memset(ad,0,sizeof(ad));
69 e[0]++;
70 for(int j=e[0];j>1;j--) swap(e[j],e[j-1]);
71 for(int j=1;j<=e[0];j++){
72 int tmp=d[j]+e[j];
73 ad[j+1]=tmp/10,d[j]=tmp%10;
74 if(ad[j]) d[j]+=ad[j];
75 if(d[j]>=10) ad[j+1]+=d[j]/10,d[j]%=10;
76 } if(ad[(d[0]=e[0])+1]) d[0]++,d[d[0]]=ad[d[d[0]]];
77 }
78 for(int i=d[0];i;i--) printf("%lld",d[i]);puts("");
79 }
80 }using namespace TASK;
81 namespace Solve{
82 const int base=1e16;
83 struct Big_Int{
84 int p[65];
85 Big_Int(){}
86 Big_Int(int x){memset(p,0,sizeof(p));p[0]=(x>0);p[1]=x;}
87 inline void print(){
88 printf("%lld",p[p[0]]);
89 for(int i=p[0]-1;i>0;--i) printf("%016lld",p[i]);
90 puts("");
91 }
92 Big_Int operator*(const int&x){
93 Big_Int ret; memset(ret.p,0,sizeof(ret.p)); int add=0; ret.p[0]=p[0];
94 for(int i=1;i<=ret.p[0];++i){
95 ret.p[i]=p[i]*x+add;
96 add=ret.p[i]/base;
97 ret.p[i]-=add*base;
98 }
99 if(add) ret.p[++ret.p[0]]=add;
100 return ret;
101 }
102 Big_Int operator+(const Big_Int&a){
103 Big_Int ret; memset(ret.p,0,sizeof(ret.p)); int add=0; ret.p[0]=max(a.p[0],p[0]);
104 for(int i=1;i<=ret.p[0];++i){
105 ret.p[i]=a.p[i]+p[i]+add;
106 add=ret.p[i]/base;
107 if(ret.p[i]>=base) ret.p[i]-=base;
108 }
109 if(add) ret.p[++ret.p[0]]=add;
110 return ret;
111 }
112 };
113 pair<Big_Int,Big_Int> f[505][1<<9];
114 pair<Big_Int,Big_Int> dfs(int pos,int sta){
115 if(f[pos][sta].first.p[1]>-1) return f[pos][sta];
116 if(pos>n) return f[pos][sta]=make_pair(Big_Int(1),Big_Int(0));
117 f[pos][sta].first.p[1]=0;
118 for(int i=1;i<=k;i++) if(!(sta&(ban[i]))){
119 pair<Big_Int,Big_Int> res=dfs(pos+1,sta|(1<<i-1));
120 f[pos][sta].first=f[pos][sta].first+res.first;
121 f[pos][sta].second=f[pos][sta].second+(res.first*i)+(res.second*10);
122 }
123 return f[pos][sta];
124 }
125 }using namespace Solve;
126 namespace WSN{
127 inline short main(){
128 freopen("hacker2.in","r",stdin);
129 freopen("hacker2.out","w",stdout);
130 n=read();m=read();k=read();
131 if(!m) return task1(),0;
132 for(int i=1,a,b;i<=m;++i) a=read(),b=read(),ban[a]|=1<<b-1;
133 for(int i=1;i<=n+1;i++)
134 for(int j=0;j<(1<<k);j++) f[i][j].first=Big_Int(-1);
135 pair<Big_Int,Big_Int> ans=dfs(1,0);
136 ans.first.print(); ans.second.print();
137 return 0;
138 }
139 }
140 signed main(){return WSN::main();}
Noip模拟69 2021.10.5的更多相关文章
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟81 2021.10.20
T1 语言 比较简单的题,然后就瞎写了,所以考场上就我一个写了线段树的,所以我的常数.... 所以就枚举动词的位置,找前面后面有没有出现$4$即可 1 #include<bits/stdc++. ...
- Noip模拟83 2021.10.26
T1 树上的数 有手就能在衡中$OJ$上过,但是$WaitingCoders$不行,就是这样 必须使用$O(n)$算法加上大力卡常,思路就是找子树内没更新的更新,更新过了直接$return$ 1 #i ...
- Noip模拟80 2021.10.18
预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...
- Noip模拟79 2021.10.17(题目名字一样)
T1 F 缩点缩成个$DAG$,然后根据每个点的度数计算期望值 1 #include<cstdio> 2 #include<cstring> 3 #include<vec ...
- Noip模拟78 2021.10.16
这次时间分配还是非常合理的,但可惜的是$T4$没开$\textit{long long}$挂了$20$ 但是$Arbiter$上赏了蒟蒻$20$分,就非常不错~~~ T1 F 直接拿暴力水就可以过,数 ...
- Noip模拟77 2021.10.15
T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...
- Noip模拟75 2021.10.12
T1 如何优雅的送分 他说是送分题,我就刚,没刚出来,想到莫比乌斯容斥后就都没推出来 好吧还是不能被恶心的题目,挑衅的语言打乱做题节奏 于是这一场也就没了.... $F(i)$表示$i$的不同质因子集 ...
随机推荐
- C语言实现有限状态机
1. 什么是有限状态机 有限状态机在百度百科上的解释为: 有限状态自动机(FSM "finite state machine" 或者FSA "finite state a ...
- Postman调试Abp API
在swagger中查看登录需要用post方式访问,Abp需要用application/json方式调用 请求体 Postman调用方式 例:访问所有用户,调用Api地址为http://localhos ...
- Git:为Git Bash.exe设置默认起始目录的两种方式(start in、~/.bashrc)
在协作开发的过程中,我们经常要进行一些项目的上传拉取操作. 在无数次不厌其烦的打开关闭 Git Bash 后,我实在忍受不了作为一个程序员还要每次都要进行如下的小白操作了 cd /d/my-proje ...
- NOIP模拟51
樱花满地集于我心,楪舞纷飞祈愿相随 前言 太菜了,人手切掉两个题,我竟然一道都不会.. 改 T3 的时候整个人的心态都崩掉了,一部分原因可能是语文素养不高导致我看不懂题解. 另一部分可能就是系太不太好 ...
- 清除router路由后面的参数
清除router参数: 1.this.$router.push({ query: {}}) 2.var path = this.$route.path; //获取路由路径 this.$route ...
- Linux上安装服务器监视工具,名为Scout_Realtime。
如何从浏览器监视Linux服务器和进程指标 在服务器上安装Ruby 1.9.3+ sudo yum -y install rubygems-devel 在Linux系统上安装了Ruby之后,现在可以使 ...
- 使用私有gitlab发布自动生成版本号和标签(version和tag)(骚)
设置 semantic ,自动生成版本号和标签 FROM node:14-buster-slim LABEL maintainer="wangyunpeng" COPY sourc ...
- systemctl --now参数
1.我们安装一个httpd服务来测试一下 --now参数 yum install httpd 2.查看一下当前服务状态 可以看到服务没有启动 而且服务没有自启 [root@master1 ~]# s ...
- HiveServer2的负载均衡高可用与ActicePassive高可用浅析
负载均衡的高可用 最近在工作中遇到了hiveserver2需要部署高可用的场景,去网上搜索了解过后,用了绝大多数人推荐的共同方法: Property_name Property_value Descr ...
- java的运行时数据区域
最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 1.程 ...