Noip模拟15 2021.7.14
T1 夜莺与玫瑰
题目越发的变态起来。。。
这题刚开始看超级像仪仗队,好不容易码完欧拉函数后尝试×2后输出但不对!!
于是选择了跳过。。。。
正解居然是莫比乌斯函数。。。。我也是醉了
预处理完就剩下$O(1)$求解然而我做不到。。
于是打了超级恶心的前缀和$O(n^2)$预处理以及$O(Tn)$求解。
(多亏JYFHYX想到的手摸数组辗转相除超吊好吧)。
竟然还可以定义short数组防止MLE,小马长见识了。
先考虑到柿子:
$\sum_{a=1}^{n-1}\sum_{b-1}^{m-1}[gcd(a,b)==1]((n-a)(m-b)-max(n-2a,0)*max(m-2b,0))$
证明的话考虑原本筛到(a,b)点,
那么对于(1,1)到(a,b)的矩形每一个点以自己的a/b斜率向下划线作出的贡献是$(n-a)(m-b)$
然后向下再拓展出一个相同的矩形,
这个矩形与先前的那个矩形作出的贡献一样,则减去(前提保证斜率唯一特殊性,即gcd为1)
然后把括号拆开,发现一些不变的东西,
提取公因数之后发现可以维护三个前缀和(short开两个,剩下一个开int不会炸)
一个$prime_{i,j}$表示1~j中与i互质的数的个数(单为i那一层的)
一个$gcd_{i,j}$表示gcd为1的个数
一个$sum_{i,j}$表示1~j所有与i互质的数的和(单维护i那一层的)
然后通过化简的柿子算就行.


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 inline int read(){
- 4 int x=0,f=1; char ch=getchar();
- 5 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
- 6 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
- 7 return x*f;
- 8 }
- 9 const int NN=4005,p=1073741824;
- 10 int T;
- 11 int sum[NN][NN];
- 12 short gcd[NN][NN],prime[NN][NN];
- 13 inline void pre(short n){
- 14 for(short i=1;i<=n;i++){
- 15 gcd[i][i]=gcd[i][0]=gcd[0][i]=i;
- 16 for(short j=1;j<i;j++)
- 17 gcd[i][j]=gcd[j][i]=gcd[j][i%j];
- 18 }
- 19 for(short i=1;i<=n;i++){
- 20 for(short j=1;j<=n;j++){
- 21 prime[i][j]=prime[i][j-1];
- 22 sum[i][j]=sum[i][j-1];
- 23 if(gcd[i][j]==1){
- 24 prime[i][j]++;
- 25 sum[i][j]+=j;
- 26 }
- 27 }
- 28 }
- 29 }
- 30 namespace WSN{
- 31 inline int main(){
- 32 pre(4000);
- 33 // FILE *A=freopen("1.in","r",stdin);
- 34 T=read();
- 35 while(T--){
- 36 short n=read(),m=read();
- 37 long long ans=0;
- 38 for(short i=1;i<n;i++){
- 39 (ans+=(n-i)*((long long)prime[i][m-1]*m%p-sum[i][m-1]+p))%=p;
- 40 if(2*i<n)
- 41 ((ans-=(long long)(n-2*i)*(prime[i][m/2]*m%p-2*sum[i][m/2]%p))+=p)%=p;
- 42 }
- 43 printf("%lld\n",(ans*2+n+m+p)%p);
- 44 }
- 45 return 0;
- 46 }
- 47 }
- 48 signed main(){return WSN::main();}
T2 影子
此题非常之离谱,不过$n^2$暴力超好打
正解是个并查集。
先跑树链剖分,把权值排序从大到小
遍历节点将其看作一个集合并将其与所有已经vis过的儿子merge出新的集合,
同时考虑六种情况,因为并查集维护了一个最长路,则有维护构成最长路的两个端点
分别考虑两个集合的不同端点连边构成最长(4种),原来的两个集合本身就有一个是新的最长(2种)
暴力枚举情况即可。最后用这个维护好的和遍历到的点权值相乘最小值即为答案。


- 1 #include<bits/stdc++.h>
- 2 #define int long long
- 3 using namespace std;
- 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(); }
- 8 return x*f;
- 9 }
- 10 const int NN=550000;
- 11 int T,n;
- 12 int son[NN],fa[NN],dep[NN],siz[NN],top[NN],dis[NN];
- 13 struct snow{int val,id;};snow d[NN];
- 14 inline bool cmp(snow a,snow b){return a.val>b.val;}
- 15 struct SNOW{int to,val,next;};SNOW e[NN]; int head[NN],rp;
- 16 struct node{int st,ed,len,fa;};node s[NN];
- 17 bool vis[NN];
- 18 inline void add(int x,int y,int z){e[++rp]=(SNOW){y,z,head[x]}; head[x]=rp;}
- 19 inline void dfs1(int f,int x){
- 20 dep[x]=dep[f]+1; siz[x]=1; fa[x]=f;
- 21 for(int i=head[x];i;i=e[i].next){
- 22 int y=e[i].to;
- 23 if(y==f) continue;
- 24 dis[y]=dis[x]+e[i].val;
- 25 dfs1(x,y);
- 26 siz[x]+=siz[y];
- 27 if(siz[son[x]]<siz[y]) son[x]=y;
- 28 }
- 29 }
- 30 inline void dfs2(int x,int t){
- 31 top[x]=t;
- 32 if(!son[x]) return; dfs2(son[x],t);
- 33 for(int i=head[x];i;i=e[i].next){
- 34 int y=e[i].to;
- 35 if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
- 36 }
- 37 }
- 38 inline int LCA(int x,int y){
- 39 while(top[x]!=top[y]){
- 40 if(dep[top[x]]<dep[top[y]]) swap(x,y);
- 41 x=fa[top[x]];
- 42 }if(dep[x]>dep[y]) swap(x,y);
- 43 return x;
- 44 }
- 45 inline int getfa(int x){return s[x].fa==x?x:getfa(s[x].fa);}
- 46 inline void merge(int x,int y){
- 47 x=getfa(x),y=getfa(y); s[y].fa=x;
- 48 //不要直接定义新值,要不然会连不上边,merge后面的操作都是与fx,fy有关的!!!!!!!!!!!!!!!!!!!!!!
- 49 int stx=s[x].st,sty=s[y].st,edx=s[x].ed,edy=s[y].ed;
- 50 int dis1=dis[stx]+dis[sty]-2*dis[LCA(stx,sty)];
- 51 int dis2=dis[stx]+dis[edy]-2*dis[LCA(stx,edy)];
- 52 int dis3=dis[edx]+dis[sty]-2*dis[LCA(edx,sty)];
- 53 int dis4=dis[edx]+dis[edy]-2*dis[LCA(edx,edy)];
- 54 int dis5=s[y].len,dis6=s[x].len;
- 55 s[x].len=max(dis1,max(dis2,max(dis3,max(dis4,max(dis5,dis6)))));
- 56 // cout<<s[x].len<<endl;
- 57 if(s[x].len==dis1){s[x].ed=sty;return;}
- 58 if(s[x].len==dis2){s[x].ed=edy;return;}
- 59 if(s[x].len==dis3){s[x].st=sty;return;}
- 60 if(s[x].len==dis4){s[x].st=edy;return;}
- 61 if(s[x].len==dis5){s[x].st=sty; s[x].ed=edy;return;}
- 62 }
- 63 namespace WSN{
- 64 inline int main(){
- 65 // FILE *A=freopen("1.in","r",stdin);
- 66 // FILE *B=freopen("1.out","w",stdout);
- 67 T=read();
- 68 while(T--){
- 69 n=read();
- 70 int ans=0;
- 71 for(int i=1;i<=n;i++){
- 72 d[i].val=read();
- 73 d[i].id=i; s[i].fa=i;
- 74 }
- 75 for(int i=1;i<n;i++){
- 76 int u=read(),v=read(),w=read();
- 77 add(u,v,w); add(v,u,w);
- 78 }
- 79 dfs1(0,1); dfs2(1,1);
- 80 sort(d+1,d+n+1,cmp);
- 81 for(int i=1;i<=n;i++){
- 82 int nd=d[i].id,vv=d[i].val;
- 83 vis[nd]=1; s[nd].st=s[nd].ed=nd;
- 84 s[nd].len=0;
- 85 for(int j=head[nd];j;j=e[j].next){
- 86 int to=e[j].to;
- 87 if(vis[to]&&getfa(nd)!=getfa(to)) merge(nd,to);
- 88 }
- 89 ans=max(ans,vv*s[getfa(nd)].len);
- 90 }
- 91 printf("%lld\n",ans);
- 92 rp=0; for(int i=1;i<=n;i++) head[i]=0,dis[i]=0,son[i]=0,vis[i]=0;
- 93 memset(s,0,sizeof(s)); memset(d,0,sizeof(d));
- 94 }
- 95 return 0;
- 96 }
- 97 }
- 98 signed main(){return WSN::main();}
T3 玫瑰花精
看这题时给我的时间已经不多了,虽然看出跟hotel那题差不多但是没空阁哪里扣线段树了。
线段树中维护四个量。分别为在区间内最左,最右的花精位置,中间点,花精应放置的最优位置,
剩下的思路清晰,线段树板子一打。就剩下pushdown搁哪里空着啥也不会。。
考虑n种情况,其实先预先画个图,把维护的东西标识清楚情况自然出来了,剩下的代码也好理解。
- 1 void pushup(int id){
- 2 le[id]=le[lid]?le[lid]:le[rid];
- 3 ri[id]=ri[rid]?ri[rid]:ri[lid];
- 4 if(!le[lid]){mi[id]=mi[rid];po[id]=po[rid];return;}
- 5 if(!le[rid]){mi[id]=mi[lid];po[id]=po[lid];return;}
- 6 int cmo=(le[rid]-ri[lid])>>1;
- 7 int an=max(cmo,max(mi[lid],mi[rid]));
- 8 if(an==mi[lid]){mi[id]=mi[lid]; po[id]=po[lid];return;}
- 9 else if(an==cmo){mi[id]=cmo; po[id]=(le[rid]+ri[lid])>>1;return;}
- 10 else{mi[id]=mi[rid]; po[id]=po[rid];return;}
- 11 }
纤细的pushdown。。。
$fairy[x]$记录花精x的位置,注意输出时判断的三种情况。如果树是空树直接输出1。


- 1 #include<bits/stdc++.h>
- 2 #define lid (id<<1)
- 3 #define rid (id<<1|1)
- 4 using namespace std;
- 5 inline int min(int a,int b){return a<b?a:b;}
- 6 inline int max(int a,int b){return a>b?a:b;}
- 7 inline int read(){
- 8 int x=0,f=1; char ch=getchar();
- 9 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
- 10 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
- 11 return x*f;
- 12 }
- 13 const int NN=3000000,inf=0x7fffffff;
- 14 int n,m,fairy[NN];
- 15 struct SNOWtree{
- 16 int ll[NN<<2],rr[NN<<2];
- 17 int le[NN<<2],ri[NN<<2],mi[NN<<2],po[NN<<2];
- 18 void pushup(int id){
- 19 le[id]=le[lid]?le[lid]:le[rid];
- 20 ri[id]=ri[rid]?ri[rid]:ri[lid];
- 21 if(!le[lid]){mi[id]=mi[rid];po[id]=po[rid];return;}
- 22 if(!le[rid]){mi[id]=mi[lid];po[id]=po[lid];return;}
- 23 int cmo=(le[rid]-ri[lid])>>1;
- 24 int an=max(cmo,max(mi[lid],mi[rid]));
- 25 if(an==mi[lid]){mi[id]=mi[lid]; po[id]=po[lid];return;}
- 26 else if(an==cmo){mi[id]=cmo; po[id]=(le[rid]+ri[lid])>>1;return;}
- 27 else{mi[id]=mi[rid]; po[id]=po[rid];return;}
- 28 }
- 29 void build(int id,int l,int r){
- 30 ll[id]=l; rr[id]=r;
- 31 if(l==r) return;
- 32 int mid=(l+r)>>1;
- 33 build(lid,l,mid); build(rid,mid+1,r);
- 34 }
- 35 void update(int id,int pos){
- 36 if(ll[id]==rr[id]){
- 37 le[id]=ri[id]=pos;
- 38 mi[id]=po[id]=0;
- 39 return;
- 40 }
- 41 int mid=(ll[id]+rr[id])>>1;
- 42 if(pos<=mid) update(lid,pos);
- 43 else update(rid,pos);
- 44 pushup(id);
- 45 }
- 46 void dele(int id,int pos){
- 47 if(ll[id]==rr[id]){
- 48 le[id]=ri[id]=mi[id]=po[id]=0;
- 49 return;
- 50 }
- 51 int mid=(ll[id]+rr[id])>>1;
- 52 if(pos<=mid) dele(lid,pos);
- 53 else dele(rid,pos);
- 54 pushup(id);
- 55 }
- 56 }tr;
- 57 namespace WSN{
- 58 inline int main(){
- 59 // FILE *A=freopen("1.in","r",stdin);
- 60 // FILE *B=freopen("1.out","w",stdout);
- 61 n=read();m=read();
- 62 tr.build(1,1,n);
- 63 for(int i=1;i<=m;i++){
- 64 int opt=read(),x=read();
- 65 if(opt==1){
- 66 // cout<<tr.le[1]-1<<" "<<tr.mi[1]<<" "<<n-tr.ri[1]<<endl;
- 67 // for(int j=1;j<=n*4;j++) if(tr.ll[j])
- 68 // cout<<tr.ll[j]<<" "<<tr.rr[j]<<" "<<tr.le[j]<<" "<<tr.ri[j]<<" "<<tr.mi[j]<<endl;
- 69 if(!tr.le[1]){
- 70 tr.update(1,1);
- 71 puts("1"); fairy[x]=1;
- 72 continue;
- 73 }
- 74 else{
- 75 int an=max(tr.le[1]-1,max(n-tr.ri[1],tr.mi[1]));
- 76 if(an==tr.le[1]-1){
- 77 puts("1");
- 78 fairy[x]=1;
- 79 tr.update(1,1);
- 80 continue;
- 81 }
- 82 else if(an==tr.mi[1]){
- 83 printf("%d\n",tr.po[1]);
- 84 fairy[x]=tr.po[1];
- 85 tr.update(1,tr.po[1]);
- 86 continue;
- 87 }
- 88 else{
- 89 printf("%d\n",n);
- 90 fairy[x]=n;
- 91 tr.update(1,n);
- 92 continue;
- 93 }
- 94 }
- 95 }
- 96 if(opt==2){
- 97 tr.dele(1,fairy[x]);
- 98 fairy[x]=0;
- 99 continue;
- 100 }
- 101 }
- 102 return 0;
- 103 }
- 104 }
- 105 signed main(){return WSN::main();}
Noip模拟15 2021.7.14的更多相关文章
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- Noip模拟53 2021.9.14
T1 ZYB和售货机 首先这道题有两种做法. 一种是发现每个点都可以先被取到只剩一个,只要收益大于$0$ 然后发现建一个$i->f[i]$的图时出现环,要把它去掉, 那么跑一个$tarjan$枚 ...
- Noip模拟39 2021.8.14
T1 打地鼠 都切掉了的简单题 1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 con ...
- Noip模拟77 2021.10.15
T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...
- Noip模拟40 2021.8.15
T1 送花 按照题解意思说是扫描线题,但我觉得像一个线段树优化$dp$ 主要思想一样,就是暴力枚举右端点,同时维护左端点的最值, 考虑两种情况, 如果左端点在$r$扫到的数$i$上一次出现的位置之前, ...
- Noip模拟16 2021.7.15
题目真是越来越变态了 T1 Star Way To Heaven 首先,你要看出这是一个最小生成树的题(妙吧?) 为什么可以呢? 我们发现从两点连线的中点过是最优的,但是上下边界怎么办呢? 我们把上下 ...
- Noip模拟70 2021.10.6
T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...
- Noip模拟69 2021.10.5
考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...
- Noip模拟63 2021.9.27(考场惊现无限之环)
T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...
随机推荐
- Linux的基础指令(二)
目录: 一.列表显示目录内容-ls 二.设置别名-alias 三.统计目录及文件空间占用情况-du 四.创建新目录 -mkdir 五.创建空文件-to ...
- WPF 第三方资源
1.XCeed 开发的Extended WPF Toolkit http://wpftoolkit.codeplex.com/ http://www.csdn123.com/html/blogs/20 ...
- python 打字小游戏
最近随便用python的pygame编了这个打字小游戏 只要有字母调到窗口底部就结束 上代码: import pygame.freetype import sys import random pyga ...
- [Navicat15 试用期过期解决办法]
Navicat15 试用期过期解决办法 第一步:关闭Navicat 第二步: 打开注册表编辑器,win + R, 输入regedit 第三步: 在最上方搜索框输入HKEY_CURRENT_USER\S ...
- 建立 F103C8T6 HAL库 Makefile FreeRTOS 工程
F103C8T6 HAL库 Makefile FreeRTOS 工程模板 环境 该工程的开发平台为 ARM-GCC 工具链和 Make > arm-none-eabi-gcc -v gcc ve ...
- shell脚本中 /dev/null 的用途
/dev/null 是一个特殊的设备文件,它丢弃一切写入其中的数据 可以将它 视为一个黑洞, 它等效于只写文件, 写入其中的所有内容都会消失, 尝试从中读取或输出不会有任何结果,同样,/dev/nul ...
- tomcat 跨域的配置
* 允许所有跨域 E:\apache-tomcat-7.0.81\conf\web.xml <filter> <filter-name>CorsFilter</fil ...
- 1.3redis小结--配置php reids拓展
1.执行php文件 输出phpinfo(); <?php phpinfo(); 2.根据PHPinfo的信息确定需要下载的 php_redis.dll , php_igbinary.dll 版 ...
- IP多播与NAT地址转化
IP多播 与单播相比,在一对多的通信中,多播可以大大减少网络资源.在互联网上进行多播就叫做IP多播,IP多播所传送的分组需要使用IP多播地址. 如果某台主机想要收到某个特定的多播分组,那么怎样才能是这 ...
- 深入理解Java虚拟机之JVM内存布局篇
内存布局**** JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JVM的稳定高效运行.不同的JVM对于内存的划分方式和管理机制存在部分差异.结合JVM虚拟机规范,一起来 ...