题目分析

神仙题(确信)

首先,j−aij-a _ ij−ai​和ai−ja _ i-jai​−j互为相反数,若其中最小值为bib _ ibi​,则一个为bib _ ibi​一个为m−bim-b _ im−bi​。(以下运算均在模mmm意义下进行)

j−ai=bij-a _ i = b _ ij−ai​=bi​即j=ai+bij= a _ i + b _ ij=ai​+bi​

ai−j=bia _ i - j = b _ iai​−j=bi​即j=ai−bij= a _ i - b _ ij=ai​−bi​

j−ai=−bij-a _ i = -b _ ij−ai​=−bi​即j=ai−bij= a _ i - b _ ij=ai​−bi​

ai−j=−bia _ i - j = -b _ iai​−j=−bi​即j=ai+bij= a _ i + b _ ij=ai​+bi​

所以jjj只有一种或两种取值。

由于原图有完美匹配,根据霍尔定理,对于任意一个妹子的子集SSS,与其有边相连的男生集合YSY _ SYS​都满足∣YS∣≥∣S∣|Y _ S| \geq |S|∣YS​∣≥∣S∣。所以若我们将一个妹子可以找的两个男生之间连一条边(若只能找一个男生,就连个自环),那么对于任意一个男生子集TTT,在这个子集中的边数都小于等于点数,所以任意一个连通块,要么是树,要么是基环树。

假如妹子iii选择男生aaa获得愉悦度waw _ awa​,选择男生bbb获得愉悦度wbw _ bwb​,则连边(b,a,wa)(b,a,w _ a)(b,a,wa​)和(a,b,wb)(a,b,w _ b)(a,b,wb​),这两条边只能选一条也必须选一条,并且每个男生点的入度都最多为111。

对于树,一定是以某个点为根的一棵外向树形图。所以用dfs序为下标建立线段树,每个位置维护以这个点为根的外向树贡献是多少,改一条边权值时维护一下即可。

对于基环树,环外的树一定都是外向的,有些边是必选有些是必不选。环的话,存一下环两个方向的贡献,修改时维护。

然后我们都知道,基环树的题目思路听起来简单,写死人。

实现上,我是记录了一条边属于哪一种边,分别是:

0:基环树上必不选的树边,1:树上的边,2:基环树环上方向L的边,3:基环树环上方向R的边 4:基环树上必选的树边

0:直接跳过。

1:分类讨论,是xxx一侧的点为外向树树根时这条边会做贡献,还是yyy一侧,化为dfs序区间在线段树上修改,查询最大值。

2,3:直接开个数组记录一下

4:直接加上贡献

代码

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {int q=0;char ch=' ';while(ch<'0'||ch>'9') ch=getchar();while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();return q;
}
const int N=500005;
int n,m,T,Q,tot,tim,top,ccnt,tcnt,ans;
int a[N],b[N],h[N],ne[N<<1],to[N<<1],w[N<<1],rev[N<<1];
int vis[N],dsu[N],tag[N],typ[N<<1];
int in[N],out[N],fa[N],tr[N<<2],lz[N<<2],rt[N];
int st[N],id[N<<1],Lv[N],Rv[N];
//typ:边的类型,Lv:基环树方向L的边权和,Rv:基环树方向R的边权和
//dsu:并查集,rev:反向边,id:基环树边记录基环树编号,树边记录根void add(int x,int y,int z) {to[++tot]=y,ne[tot]=h[x],h[x]=tot,w[tot]=z;}
int getdsu(int x) {return x==dsu[x]?x:dsu[x]=getdsu(dsu[x]);}void pd(int i) {int l=i<<1,r=(i<<1)|1;tr[l]+=lz[i],tr[r]+=lz[i],lz[l]+=lz[i],lz[r]+=lz[i],lz[i]=0;
}
void modify(int l,int r,int s,int t,int i,int v) {if(l<=s&&t<=r) {lz[i]+=v,tr[i]+=v;return;}int mid=(s+t)>>1;if(lz[i]) pd(i);if(l<=mid) modify(l,r,s,mid,i<<1,v);if(mid+1<=r) modify(l,r,mid+1,t,(i<<1)|1,v);tr[i]=max(tr[i<<1],tr[(i<<1)|1]);
}
int query(int l,int r,int s,int t,int i) {if(l<=s&&t<=r) return tr[i];int mid=(s+t)>>1,re=0; if(lz[i]) pd(i);if(l<=mid) re=query(l,r,s,mid,i<<1);if(mid+1<=r) re=max(re,query(l,r,mid+1,t,(i<<1)|1));return re;
}
void work_tree(int t,int v) {//分类讨论某条树边对整棵树不同根时的影响int x=to[t],y=to[rev[t]];if(x==fa[y]) modify(in[y],out[y],1,tim,1,v);else modify(in[id[t]],out[id[t]],1,tim,1,v),modify(in[x],out[x],1,tim,1,-v);
}void dfs_tree(int x,int rt,int las) {in[x]=++tim,fa[x]=las,vis[x]=1;for(RI i=h[x];i;i=ne[i])if(to[i]!=las)dfs_tree(to[i],rt,x),id[i]=id[rev[i]]=rt,typ[i]=typ[rev[i]]=1;out[x]=tim;
}
void dfs_circle(int x,int y,int no,int las) {fa[x]=las,vis[x]=1;if(x==y) {for(RI i=1;i<=top;++i) {typ[st[i]]=2,Lv[ccnt]+=w[st[i]];typ[rev[st[i]]]=3,Rv[ccnt]+=w[rev[st[i]]];}}for(RI i=h[x];i;i=ne[i])if(to[i]!=las&&i!=no&&i!=rev[no]) {id[i]=id[rev[i]]=ccnt,typ[i]=4;st[++top]=i,dfs_circle(to[i],y,no,x),--top;}
}
void prework() {for(RI i=1;i<=m;++i) {if(vis[i]) continue;int k=getdsu(i);if(!tag[k]) dfs_tree(i,i,0),rt[++tcnt]=i;else {++ccnt,dfs_circle(to[tag[k]],to[rev[tag[k]]],tag[k],0);id[tag[k]]=id[rev[tag[k]]]=ccnt;typ[tag[k]]=2,Lv[ccnt]+=w[tag[k]];if(tag[k]!=rev[tag[k]]) typ[rev[tag[k]]]=3,Rv[ccnt]+=w[rev[tag[k]]];//注意自环的特判ans+=max(Lv[ccnt],Rv[ccnt]);}}for(RI i=1;i<=tot;++i)if(typ[i]==4) ans+=w[i];else if(typ[i]==1) work_tree(i,w[i]);for(RI i=1;i<=tcnt;++i) ans+=query(in[rt[i]],out[rt[i]],1,tim,1);
}void work() {Q=read(),printf("%d\n",ans);while(Q--) {int x=read()-ans*T,y=read()-ans*T;if(typ[x]==0);else if(typ[x]==1) {int kv=query(in[id[x]],out[id[x]],1,tim,1);work_tree(x,y-w[x]),w[x]=y;ans+=query(in[id[x]],out[id[x]],1,tim,1)-kv;}else if(typ[x]==2) {int kv=max(Lv[id[x]],Rv[id[x]]);Lv[id[x]]+=y-w[x],w[x]=y;ans+=max(Lv[id[x]],Rv[id[x]])-kv;}else if(typ[x]==3) {int kv=max(Lv[id[x]],Rv[id[x]]);Rv[id[x]]+=y-w[x],w[x]=y;ans+=max(Lv[id[x]],Rv[id[x]])-kv;}else if(typ[x]==4) ans+=y-w[x],w[x]=y;printf("%d\n",ans);}
}int main()
{n=read(),m=read(),T=read();for(RI i=0;i<n;++i) a[i]=read();for(RI i=0;i<n;++i) b[i]=read();for(RI i=1;i<=m;++i) dsu[i]=i;for(RI i=0;i<n;++i) {int x=(a[i]+b[i])%m+1,y=(a[i]-b[i]+m)%m+1;if(x>y) swap(x,y);add(y,x,read());int r1=getdsu(x),r2=getdsu(y);if(r1==r2) tag[r1]=tot;else dsu[r1]=r2,tag[r2]|=tag[r1];if(x!=y) rev[tot]=tot+1,rev[tot+1]=tot,add(x,y,read());else rev[tot]=tot;}prework(),work();return 0;
}

loj 523 「LibreOJ β Round #3」绯色 IOI(悬念) 霍尔定理+基环树+线段树相关推荐

  1. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 -- 接着他们发现自己收 ...

  2. [LOJ #521]「LibreOJ β Round #3」绯色 IOI(抵达)(结论)

    #521. 「LibreOJ β Round #3」绯色 IOI(抵达) description solution 因为点的庇护所不能为自身,题目背景在树上,有结论一定是两个相邻点互为庇护所 所以树一 ...

  3. #520. 「LibreOJ β Round #3」绯色 IOI(开端) 贪心

    妈耶,没脸见人了.巨水,想出来不写,人生重来算了. 就是个找规律题,相邻一个连一下,但是我没注意到是IOI赛制,以为是OI赛制所以没打,感觉70分好打但是懒得了.. 证明就是把相邻3个列一下式子就出来 ...

  4. 【LOJ520】「LibreOJ β Round #3」绯色 IOI(开端)

    传送门 题解: 排序. 现在问题是找出两条从111到nnn的路径使得代价最小. 显然路径上点的编号只可能递增. 容易证明iii和i+1i+1i+1不能存在于同一条路径中.考虑p<i<i+1 ...

  5. 「LibreOJ β Round #3」绯色 IOI(抵达)

    [题解] 我们可以发现叶子节点的关联点一定是它的父亲节点,那么我们dfs一遍就可以求出所有节点的关联点,或者判断出无解. 对于每个点i,它的关联点u的危险度肯定比它连接的其他点vi的危险度小,我们从u ...

  6. 【联合选讲】「LibreOJ β Round #3」绯色 IOI(悬念)

    题目 Description 胖头鱼从鱼戏团逃脱后,被主人一路追捕,他慌不择路地跑进了一颗n个节点的池子树,池子树的所有度数为1的点就是出口. 假如他现在在节点i,那么每个时刻他能选择向某个与当前点有 ...

  7. [匹配+拓扑] LibreOJ #521. 「LibreOJ β Round #3」绯色 IOI(抵达)

    题意 戳这里 题解 这题一开始感觉无从下手,所以我们要尝试得到一些结论. 自己画一画可以发现,一定是两两互为对方的庇护所.这样才有可能保证任意两个不同的城市庇护所不同.否则由于原图没有环,到后面必定会 ...

  8. [结论] LibreOJ #520. 「LibreOJ β Round #3」绯色 IOI(开端)

    题意 戳这里 题解 这是一道结论题. 我们先把数放到数轴上考虑.定义两个点的距离为几何上的距离的平方. 我们可以把一个回路看作两条从 11 到 nn 的不相交的路径. 有一种经典的二路取数的 O(n2 ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分...

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

最新文章

  1. 《设计的品格 探索×呈现×进化的InDesign美学》—第1课1.4节单位和度量
  2. linux系统中tar命令的使用,linux 系统的tar命令使用方法详解
  3. Linux运行jmeter
  4. javafx 图标_JavaFX技巧32:需要图标吗? 使用Ikonli!
  5. linux将屏幕输出到文件,Linux命令执行的屏幕输出内容重定向到日志文件
  6. 来点干货 | Android 常见内存泄漏与优化(二)
  7. [使用心得]maven2之m2eclipse使用手册之二m2eclipse功能介绍
  8. SnagIt - 专业的截图工具
  9. linux终端怎么设置monaco,Ubuntu中使用Monaco字体美化
  10. POJ3345 Bribing FIPA(树形DP)
  11. virtualxposed使用教程_VirtualXposed框架虚拟机——无需root体验xposed框架
  12. bottleneck网络结构
  13. QML用径向渐变做波纹效果
  14. Coding and Paper Letter(七十)
  15. 在 iOS 中对接收到的网络数据(NSData)进行文件读写
  16. linux系统(ubuntu)下安装exe文件
  17. 2021全国电设(F题)openmv的图像识别之数字识别
  18. PHP高效生成一个不重复随机数
  19. System Toolkit for Mac(mac系统维护软件)
  20. JS模拟百度搜索框和选项卡

热门文章

  1. 四川大学计算机网络课件,四川大学计算机网络课件3
  2. 数据交易隐私保护,数据转卖,交易公平
  3. QT下视频通话的实现
  4. 【第五届集创赛备赛】一、黄乐天老师赛事宣讲及各个赛题分析
  5. 哨兵一号下载与SNAP处理
  6. 阿里云、腾讯云、百度云、华为云哪家的性能最好?
  7. 论文阅读笔记(四)——实例分割与掩模R-CNN应用于多摄像机设置中松散的奶牛
  8. 语音识别技术之孤立词识别
  9. c语言浮点类型保留几位小数
  10. python语言处理初探——分词、词性标注、提取名词