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的更多相关文章

  1. Noip模拟76 2021.10.14

    T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...

  2. Noip模拟53 2021.9.14

    T1 ZYB和售货机 首先这道题有两种做法. 一种是发现每个点都可以先被取到只剩一个,只要收益大于$0$ 然后发现建一个$i->f[i]$的图时出现环,要把它去掉, 那么跑一个$tarjan$枚 ...

  3. Noip模拟39 2021.8.14

    T1 打地鼠 都切掉了的简单题 1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 con ...

  4. Noip模拟77 2021.10.15

    T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...

  5. Noip模拟40 2021.8.15

    T1 送花 按照题解意思说是扫描线题,但我觉得像一个线段树优化$dp$ 主要思想一样,就是暴力枚举右端点,同时维护左端点的最值, 考虑两种情况, 如果左端点在$r$扫到的数$i$上一次出现的位置之前, ...

  6. Noip模拟16 2021.7.15

    题目真是越来越变态了 T1 Star Way To Heaven 首先,你要看出这是一个最小生成树的题(妙吧?) 为什么可以呢? 我们发现从两点连线的中点过是最优的,但是上下边界怎么办呢? 我们把上下 ...

  7. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  8. Noip模拟69 2021.10.5

    考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...

  9. Noip模拟63 2021.9.27(考场惊现无限之环)

    T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...

随机推荐

  1. bean.xml配置数据源和读取配置文件配置数据源

    一.bean.xml配置数据源 bean.xml装配bean,依赖注入其属性的时候,对应实体类中属性一定要有set方法, 二.读取配置文件配置数据源 1.配置文件 bean.xml配置: classp ...

  2. git换行符自动转换导致整个文件被修改的解决方案

    不少开发者可能遇到过这个问题:从git上拉取服务端代码,然后只修改了一处地方,准备提交时,用diff软件查看,却发现整个文件都被修改了.这是git自动转换换行符导致的问题. 原因 不同操作系统使用的换 ...

  3. HCNP Routing&Switching之IS-IS路由聚合和认证

    前文我们了解了IS-IS路由渗透和开销相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15302382.html:今天我们来聊一聊IS-IS路由聚合和认 ...

  4. Android通过WebView实现新闻界面的加载

    原文链接:Android实现WebView加载网页及网页美化(简易新闻 四)_Tobey_r1的博客-CSDN博客 效果展示: 我是按照原文作者的步骤一步步来的,中间没有遇到什么问题.主要是界面中有很 ...

  5. Jwt的新手入门教程

    Jwt的新手入门教程 1.Jwt究竟是什么东东? ​ 先贴官网地址:JSON Web Tokens - jwt.io ​ ​ 再贴官方的定义: What is JSON Web Token? JSON ...

  6. Sentry 监控 - Search 搜索查询实战

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  7. P4292-[WC2010]重建计划【长链剖分,线段树,0/1分数规划】

    正题 题目链接:https://www.luogu.com.cn/problem/P4292 题目大意 给出\(n\)个点的一棵树,然后求长度在\([L,U]\)之间的一条路径的平均权值最大. 解题思 ...

  8. 深入浅出WPF-08.Event( 事件)02

    路由事件 为了方便程序中对象之间的通信常常需要我们定义一些路由事件.使用路由事件比直接事件方便得多. 创建自定义路由事件的步骤: 1)声明并注册路由 2)为路由事件添加CLR事件包装 3)创建可以激发 ...

  9. Hutool-Convert类型转换常见使用

    Convert 主要针对于java中常见的类型转化 java常见类型的转化 转化为字符串 public class HConvert { public static void main(String[ ...

  10. 【vue】使用 Video.js 播放视频

    目录 安装 引入 使用 参考文档 环境: vue 2.0+ element ui (这里的代码用了elmentui的按钮样式,可以不用elment ui的样式) 安装 在项目中安装 video.js. ...