Noip模拟54 2021.9.16
T1 选择
现在发现好多题目都是隐含的状压,不明面给到数据范围里,之凭借一句话
比如这道题就是按照题目里边给的儿子数量不超过$10$做状压,非常邪门
由于数据范围比较小,怎么暴力就怎么来
从叶子节点向上$dp$,状态$i$表示每个儿子选/不选。
考虑找到那些点可以延伸到当前的$x$节点。
我们记录一下$x$的所有直接儿子$y$,开一个$vector:son_{i,j}$记录所有可以延伸到$i$节点的$j$
转移的时候先看单点能否直接延伸到$x$,然后枚举任意两个$y,yy$,看看其子树有无两个点$z,zz$之间有连边
把合法的状态记录下来,然后枚举子集以及它补集的子集,两两合并来转移,
最后看一下删去一个子树后答案是否会变,如果不会变,证明该子树里面可以有一个点直接延伸到$x$
1 #include<bits/stdc++.h>
2 using namespace std;
3 namespace AE86{
4 inline int read(){
5 int x=0,f=1;char ch=getchar();
6 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
7 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
8 }inline void write(int x,char opt='\n'){
9 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
10 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
11 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
12 }using namespace AE86;
13
14 const int NN=1e3+5;
15 int n,m,g[NN][NN];
16 struct SNOW{int to,next;}e[NN<<1];int head[NN],rp;
17 inline void add(int x,int y){
18 e[++rp]=(SNOW){y,head[x]};head[x]=rp;
19 e[++rp]=(SNOW){x,head[y]};head[y]=rp;
20 }
21 vector<int> son[NN]; int Son[15],dp[1<<11],ans;
22
23 inline void dfs(int f,int x){
24 for(int i=head[x];i;i=e[i].next) if(f!=e[i].to) dfs(x,e[i].to);
25 int num=0;for(int i=head[x];i;i=e[i].next) if(f!=e[i].to) Son[++num]=e[i].to;
26 memset(dp,0,sizeof(dp));
27 for(int i=1;i<=num;i++)
28 for(int j=0;j<son[Son[i]].size();j++)
29 if(g[x][son[Son[i]][j]]){dp[1<<i-1]=1;break;}
30 for(int i=1;i<=num;i++){
31 for(int j=1;j<=num;j++){
32 if(i==j) continue; bool flag=0;
33 for(auto s1:son[Son[i]]){
34 for(auto s2:son[Son[j]]){
35 if(g[s1][s2]){
36 dp[(1<<i-1)|(1<<j-1)]=1;
37 flag=1; break;
38 }
39 }
40 if(flag) break;
41 }
42 }
43 }
44 int U=(1<<num)-1,res=0;
45 for(int s=0;s<=U;s++)
46 for(int t=s;t;t=(t-1)&s)
47 dp[s]=max(dp[s],dp[t]+dp[s^t]);
48 ans+=dp[U];
49 for(int i=1;i<=num;i++)
50 if(dp[U^(1<<i-1)]==dp[U])
51 for(int j=0;j<son[Son[i]].size();j++)
52 son[x].push_back(son[Son[i]][j]);
53 son[x].push_back(x);
54 }
55 namespace WSN{
56 inline short main(){
57 freopen("select.in","r",stdin);
58 freopen("select.out","w",stdout);
59 n=read();
60 for(int i=1,u,v;i<n;i++)
61 u=read(), v=read(), add(u,v);
62 m=read();
63 for(int i=1,u,v;i<=m;i++)
64 u=read(), v=read(), g[u][v]=g[v][u]=1;
65 dfs(0,1); write(ans);
66 return 0;
67 }
68 }
69 signed main(){return WSN::main();}
T2 表格
虽然超纲但是是神题,比较不错
首先发现$3*3$的表格只有六种情况,那么问题转化为任意选$3$行$3$列最后乘$6$
比较容易在把上下界限制转为上界限制,即$calc(R)*6-calc(L)*6$
然后发现题目的什么什么距离只和卡住边界的那两行两列有关,且距离为卡出来的长方形周长
不难得出一个柿子:
$\sum_{i=3}^{n}(n-i+1)(i-2)\sum_{j=3}^{min(R/2-i+1,m)}(m-j+1)(j-2)$
然后我觉得这个柿子不可能是正解(至于为什么可能是这个柿子就吊就是$O(n)$),
于是打了一个$O(n^2)$的暴力准备对拍就去考虑$log(n)$的算法,一直到快考完。。。
其实前缀和可以优化到$O(n)$的,比较显然,拆开后面的括号即可。
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 const int mod=1e9+7;
5 namespace AE86{
6 inline int read(){
7 int x=0,f=1;char ch=getchar();
8 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
9 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
10 }inline void write(int x,char opt='\n'){
11 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
12 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
13 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
14 inline int mo(int x){return x>=mod?x-mod:x;}
15 }using namespace AE86;
16 int n,m,L,R,ans,v6,v2;
17 inline int qmo(int a,int b){
18 int ans=1,c=mod; a%=c;
19 while(b){
20 if(b&1) ans=ans*a%c;
21 b>>=1; a=a*a%c;
22 } return ans;
23 }
24 inline int sig(int x){return (1+x)%mod*x%mod*v2%mod;}
25 inline int psi(int x){return x*(x+1)%mod*(2*x%mod+1)%mod*v6%mod;}
26 inline int calc(int x){
27 int ans=0,tmp,res,l,r,cnt;
28 for(int i=3;i<=n;++i){
29 l=3,r=min(m,x/2-i+2); if(l>r) continue;
30 tmp=(i-2)*(n-i+1)%mod;
31 res=(m+3)*(sig(r)-sig(l-1)+mod)%mod;
32 res=mo(res-(psi(r)-psi(l-1)+mod)%mod+mod);
33 res=mo(res-2*m%mod*(r-l+1)%mod-2*(r-l+1)%mod+mod);
34 ans=mo(ans+tmp*res%mod);
35 }
36 return ans;
37 }
38 namespace WSN{
39 inline short main(){
40 freopen("table.in","r",stdin);
41 freopen("table.out","w",stdout);
42 n=read(); m=read(); L=read(); R=read();
43 if(R<8) return puts("0"),0;
44 v6=qmo(6,mod-2); v2=qmo(2,mod-2);
45 if(L<=8&&(n+m-2)*2<=R){
46 int M=m*(m-1)%mod*(m-2)%mod;
47 int N=n*(n-1)%mod*(n-2)%mod;
48 write(M*N%mod*v6%mod); return 0;
49 }
50
51 int wsn=mo(6*calc(R)%mod-6*calc(L-1)%mod+mod);
52 write(wsn);
53 return 0;
54 }
55 }
56 signed main(){return WSN::main();}
T 40
正解是拉格朗日插值,解决多项式问题,复杂度为多项式次数平方的高级算法
详细解释以及板子可以参考$oi-wiki$
先把柿子化简到这个地步:
$\sum\limits_{i=2}^{\min(n-1,x-2)}(n-i)(i-1)\sum\limits_{j=2}^{\min(x-i,m-1)}(m-j)(j-1)$
然后对于每一个多项式分别用插值计算出结果即可,复杂度为常数级别
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 const int mod=1e9+7;
5 namespace AE86{
6 inline int read(){
7 int x=0,f=1;char ch=getchar();
8 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
9 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
10 }inline void write(int x,char opt='\n'){
11 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
12 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
13 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
14 inline int mo(int x){return x>=mod?x-mod:x;}
15 }using namespace AE86;
16 int n,m,L,R,ans,v6,v2;
17 inline int qmo(int a,int b){
18 int ans=1,c=mod; a%=c;
19 while(b){
20 if(b&1) ans=ans*a%c;
21 b>>=1; a=a*a%c;
22 } return ans;
23 }
24 inline int inv(int x){return qmo(x,mod-2);}
25 struct node{int x,y;};node Fp[10],Gp[10],Hp[10];
26
27 inline int f(int x){return (n-x)*(x-1)%mod;}
28 inline void preF(){
29 Fp[1]=(node){2,f(2)};
30 Fp[2]=(node){3,mo(Fp[1].y+f(3))};
31 Fp[3]=(node){4,mo(Fp[2].y+f(4))};
32 Fp[4]=(node){5,mo(Fp[3].y+f(5))};
33 }
34 inline int F(int x){
35 int ans=0; x%=mod;
36 for(int i=1;i<=4;i++){
37 int tmp=Fp[i].y;
38 for(int j=1;j<=4;j++) if(i!=j)
39 tmp=tmp*(x-Fp[j].x+mod)%mod*inv(Fp[i].x-Fp[j].x+mod)%mod;
40 ans=mo(ans+tmp);
41 } return ans;
42 }
43
44 inline int g(int x){return (m-x)*(x-1)%mod;}
45 inline void preG(){
46 Gp[1]=(node){2,g(2)};
47 Gp[2]=(node){3,mo(Gp[1].y+g(3))};
48 Gp[3]=(node){4,mo(Gp[2].y+g(4))};
49 Gp[4]=(node){5,mo(Gp[3].y+g(5))};
50 }
51 inline int G(int x){
52 int ans=0; x%=mod;
53 for(int i=1;i<=4;i++){
54 int tmp=Gp[i].y;
55 for(int j=1;j<=4;j++) if(i!=j)
56 tmp=tmp*(x-Gp[j].x+mod)%mod*inv(Gp[i].x-Gp[j].x+mod)%mod;
57 ans=mo(ans+tmp);
58 } return ans;
59 }
60
61 inline void preH(int x){
62 Hp[1]=(node){2,f(2)*G(x-2)%mod};
63 Hp[2]=(node){3,mo(Hp[1].y+f(3)*G(x-3)%mod)};
64 Hp[3]=(node){4,mo(Hp[2].y+f(4)*G(x-4)%mod)};
65 Hp[4]=(node){5,mo(Hp[3].y+f(5)*G(x-5)%mod)};
66 Hp[5]=(node){6,mo(Hp[4].y+f(6)*G(x-6)%mod)};
67 Hp[6]=(node){7,mo(Hp[5].y+f(7)*G(x-7)%mod)};
68 Hp[7]=(node){8,mo(Hp[6].y+f(8)*G(x-8)%mod)};
69 }
70 inline int H(int x){
71 int ans=0; x%=mod;
72 for(int i=1;i<=7;i++){
73 int tmp=Hp[i].y;
74 for(int j=1;j<=7;j++) if(i!=j)
75 tmp=tmp*(x-Hp[j].x+mod)%mod*inv(Hp[i].x-Hp[j].x+mod)%mod;
76 ans=mo(ans+tmp);
77 } return ans;
78 }
79 inline int calc(int x){
80 int ans=0; x/=2;
81 int lim1=min(x-m,n-1);
82 int lim2=max(2ll,lim1+1);
83 int lim3=min(n-1,x-2);
84 preH(x);
85 if(lim1>=2) ans=mo(ans+F(lim1)*G(m-1)%mod);
86 if(lim2<=lim3) ans=mo(ans+H(lim3)-H(lim2-1)+mod);
87 return ans;
88 }
89 namespace WSN{
90 inline short main(){
91 freopen("table.in","r",stdin);
92 freopen("table.out","w",stdout);
93 n=read(); m=read(); L=read(); R=read();
94 if(R<8) return puts("0"),0;
95 v6=qmo(6,mod-2); v2=qmo(2,mod-2);
96 if(L<=8&&(n+m-2)*2<=R){
97 int M=m*(m-1)%mod*(m-2)%mod;
98 int N=n*(n-1)%mod*(n-2)%mod;
99 write(M*N%mod*v6%mod); return 0;
100 }
101 preF(); preG();
102 int wsn=mo(6ll*calc(R)%mod-6ll*calc(L-1)%mod+mod);
103 write(wsn);
104 return 0;
105 }
106 }
107 signed main(){return WSN::main();}
T3 黑白
不会,姑姑沽
T4 打怪
比较神仙的$CDQ$分治套单调队列
处理一个$c_i$表示干掉一个怪需要多长时间
然后不难发现先打那个攻击高血条长的怪比较优,考虑按照$a*c$排序
再处理一个$e_i$表示秒杀一个怪的贡献,
$e_i=a_i\sum_{j=1}^ {i-1}c_j+a_i(c_i-1)+c_i\sum_{j=i+1}^{n}a_j$
在确定秒杀一只怪$i$的情况下,秒杀$k$怪比秒杀$j$怪更优当且仅当:
$e_i+e_j-a_i*c_j>e_k+e_i-a_i*c_k$
化简之后是一个斜率式的模样:
$a_i> \frac {e_j-e_k}{c_j-c_k}$
然后$a_i,c_j$无序,考虑$CDQ$分治,分别在$[L,mid],[mid+1,R]$区间按照$a$,$c$排序
然后单调队列维护即可
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
15 const int NN=3e5+5;
16 int n,b,A,C,ans,tot;
17 struct SNOW{
18 int a,c,e;
19 }p[NN];
20 inline bool cmp1(SNOW a,SNOW b){return a.a*b.c>a.c*b.a;}
21 inline bool cmp2(SNOW a,SNOW b){return a.a>b.a;}
22 inline bool cmp3(SNOW a,SNOW b){return a.c<b.c;}
23 int q[NN];
24 inline void merge_sort(int l,int r){
25 if(l>=r) return; int mid=(l+r)>>1;
26 merge_sort(l,mid); merge_sort(mid+1,r);
27 sort(p+l,p+mid+1,cmp3); sort(p+mid+1,p+r+1,cmp2);
28 int h=1,t=0;
29 for(int i=l;i<=mid;i++){
30 while(h<t && (p[q[t]].e-p[q[t-1]].e)*(p[i].c-p[q[t-1]].c)<=(p[i].e-p[q[t-1]].e)*(p[q[t]].c-p[q[t-1]].c) ) --t;
31 q[++t]=i;
32 }
33 for(int i=mid+1;i<=r;i++){
34 while(h<t && p[i].a*(p[q[h+1]].c-p[q[h]].c)<=(p[q[h+1]].e-p[q[h]].e)) ++h;
35 ans=min(ans,tot-p[q[h]].e-p[i].e+p[i].a*p[q[h]].c);
36 }
37 }
38
39 namespace WSN{
40 inline short main(){
41 freopen("fittest.in","r",stdin);
42 freopen("fittest.out","w",stdout);
43 n=read(); b=read();
44 for(int i=1,a,d,c;i<=n;i++){
45 a=read(); d=read(); c=ceil(1.0*d/b);
46 p[i]=(SNOW){a,c,0}; A+=a;
47 } sort(p+1,p+n+1,cmp1);
48 for(int i=1;i<=n;i++){
49 A-=p[i].a; C+=p[i].c;
50 p[i].e=p[i].a*(C-1)+p[i].c*A;
51 ans+=p[i].a*(C-1);
52 }
53 tot=ans;
54 merge_sort(1,n);
55 write(ans);
56 return 0;
57 }
58 }
59 signed main(){return WSN::main();}
Noip模拟54 2021.9.16的更多相关文章
- Noip模拟78 2021.10.16
这次时间分配还是非常合理的,但可惜的是$T4$没开$\textit{long long}$挂了$20$ 但是$Arbiter$上赏了蒟蒻$20$分,就非常不错~~~ T1 F 直接拿暴力水就可以过,数 ...
- Noip模拟41 2021.8.16
T1 你相信引力吗 对于区间的大小关系问题,往往使用单调栈来解决 这道题的优弧和劣弧很烦,考虑将其等价的转化 由于所有的合法情况绕过的弧都不会经过最高的冰锥, 又因为环可以任意亲定起点,这样可以直接把 ...
- Noip模拟17 2021.7.16
我愿称这场考试为STL专练 T1 世界线 巧妙使用$bitset$当作vis数组使用,内存不会炸,操作还方便,的确是极好的. 但是这个题如果不开一半的$bitset$是会炸内存的,因为他能开得很大,但 ...
- 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模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
- Noip模拟61 2021.9.25
T1 交通 考场上想了一个$NPC$.应该吧,是要求出图里面的所有可行的不重复欧拉路 无数种做法都无法解出,时间也都耗在这个上面的,于是就考的挺惨的 以后要是觉得当前思路不可做,就试着换一换思路,千万 ...
- Noip模拟59 2021.9.22
新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...
随机推荐
- JS010. 三元运算符扩展运用(多层判断语句 / 多条表达式)
MDN - 三元运算符 语法 Condition ? exprIfTrue : exprIfFalse 用例: function getFee(isMember) { return(isMember ...
- GC-优化-案例
优化案例 Service S 优化 现在看一下执行jstat -gcutil的结果 S0 S1 E O P YGC YGCT FGC FGCT GCT 12.16 0.00 5.18 63.78 20 ...
- 使用Java api对HBase 2.4.5进行增删改查
1.运行hbase 2.新建maven项目 2.将hbase-site.xml放在项目的resources文件夹下 3.修改pom.xml文件,引入hbase相关资源 <repositories ...
- CentOS8部署tftp
tftp:简单文本传输协议,而ftp:文本传输协议.可以把tftp看成是ftp的精简版.tftp用于免登录传输小文件,tftp服务端监听在udp协议的69端口tftp简单的工作原理: tftp服务端与 ...
- Django学习day11随堂笔记
今日考题 """ 今日考题 1.简述自定义分页器的使用 2.forms组件是干什么用的,它的主要功能有哪些功能,你能否具体说说每个功能下都有哪些经常用到的方法及注意事项( ...
- CPU到底是什么东西?它为什么能够执行数学运算?
CPU到底是什么东西?它为什么能够执行数学运算? 本文地址http://yangjianyong.cn/?p=20转载无需经过作者本人授权 简单的物理电路 先来看一张初中学过的物理电路图: 从图中我们 ...
- vue跳转路由
1. router-link 1. 不带参数 <router-link :to="{name:'home'}"> <router-link :to=" ...
- 深入xLua实现原理之C#如何调用Lua
本文主要是探讨xLua下C#调用Lua的实现原理,有关Lua如何调用C#的介绍可以查看深入xLua实现原理之Lua如何调用C# C#与Lua数据通信机制 无论是Lua调用C#,还是C#调用Lua,都需 ...
- php 单向链表反转 reverse (没有空的头结点)
* 参照php标准库设计接口 http://php.net/manual/en/class.spldoublylinkedlist.php * 反转单向链表 reverse方法, 其他的方法为了方便测 ...
- php 设计模式 --适配器
1,目标:实现一个不同的类不同方法,符合一定的规范: 规范类 <?php interface Iplay{ function Attack(); function Defence(); } cl ...