T1 牛半仙的妹子图


做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数。

我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm挺优秀。

后来发现wlr都是1e9,一个个求前缀和直接炸了,考场上感觉l,r,w差值对答案有影响就没离散化,开了个map记出现的w的前缀和,其他都能O1计算。

这不切了吗?年轻的我如是想到。

于是我领略到了map80倍常数的威力。离散化开数组再带到初值计算就A了。

考场拿了75pts还WA了仨点,据WTZ说要大力分类讨论,但我改对离散化直接切了,不大懂。

code:

 1 #include<bits/stdc++.h>
2 #define debug exit(0)
3 #define int long long
4 #define rin register signed
5 using namespace std;
6 const int NN=5e5+5;
7 struct edge{
8 int st,to,nex,w;
9 }e[NN];
10 struct bcj{
11 int fa;
12 bitset<650>gl;
13 }p[NN];
14 int n,m,q,x,M,opt,head[NN],num,c[NN],ans,maxr,l[10005],r[10005];
15 int has[NN],ext,pre[NN],ts[NN];
16 inline bool cmp(edge a,edge b){ return a.w<b.w; }
17 inline int getfa(int a){ return p[a].fa==a?a:p[a].fa=getfa(p[a].fa); }
18 inline int read(){
19 int x=0,f=1;
20 char ch=getchar();
21 while(ch<'0'||ch>'9'){
22 if(ch=='-') f=-1;
23 ch=getchar();
24 }
25 while(ch>='0'&&ch<='9'){
26 x=(x<<1)+(x<<3)+(ch^48);
27 ch=getchar();
28 }
29 return x*f;
30 }
31 void write(int x){
32 if(x<0) putchar('-'), x=-x;
33 if(x>9) write(x/10);
34 putchar(x%10+'0');
35 }
36 void lsh(){
37 for(int i=1;i<=m;i++) has[i]=e[i].w;
38 ext=unique(has+1,has+1+m)-has-1;
39 for(int i=1;i<=m;i++)
40 e[i].w=lower_bound(has+1,has+ext+1,e[i].w)-has;
41 }
42 inline void add(int a,int b,int d){
43 e[++num].to=b; e[num].nex=head[a]; head[a]=num; e[num].w=d; e[num].st=a;
44 }
45 void gather(int a,int b){
46 a=getfa(a); b=getfa(b);
47 if(a==b) return;
48 p[b].fa=a; p[a].gl|=p[b].gl;
49 }
50 signed main(){
51 n=read(); m=read(); q=read(); x=read(); opt=read(); ts[0]=1;
52 if(opt) M=read();
53 for(rin i=1;i<=n;i++){
54 c[i]=read();
55 p[i].fa=i; p[i].gl[c[i]]=1;
56 }
57 for(rin i=1;i<=m;i++){
58 int u=read(),v=read(),w=read();
59 add(u,v,w);
60 } sort(e+1,e+m+1,cmp);
61 lsh();
62 for(rin i=1;i<=m;i++){
63 int u=e[i].st,v=e[i].to;
64 gather(u,v);
65 if(e[i].w!=e[i+1].w){
66 ts[e[i].w]=p[getfa(x)].gl.count();
67 pre[e[i].w]=pre[e[i].w-1]+ts[e[i].w-1]*(has[e[i].w]-has[e[i].w-1]-1);
68 pre[e[i].w]+=ts[e[i].w];
69 }
70 }
71 for(rin i=1;i<=q;i++){
72 int l=read(),r=read();
73 if(opt) l=(l^ans)%M+1, r=(r^ans)%M+1;
74 if(l>r) swap(l,r); l--;
75 int wl=upper_bound(has,has+ext+1,l)-has-1;
76 int wr=upper_bound(has,has+ext+1,r)-has-1;
77 ans=pre[wr]+ts[wr]*(r-has[wr]);
78 ans-=pre[wl]+ts[wl]*(l-has[wl]);
79 write(ans); putchar('\n');
80 }
81 return 0;
82 }

T1

T2 牛半仙的妹子tree


考场暴力炸了,只有10pts。

题解里正解好像是分块,好像还能点分树,机房里还看到了很多奇奇怪怪的AC代码,

但最快的竟然是求LCA暴力判断就离谱。

记录染色的点和染色的时间,查询时枚举比较时间差和距离即可。

树剖竟然只400多ms?

code:

 1 #include<bits/stdc++.h>
2 #define debug exit(0)
3 #define ii pair<int,int>
4 #define mp make_pair
5 #define fi first
6 #define se second
7 #define pb push_back
8 using namespace std;
9 const int NN=1e5+5;
10 int n,m,x,to[NN<<1],nex[NN<<1],head[NN],opt,num;
11 int dep[NN],son[NN],siz[NN],dfn[NN],id[NN],fa[NN],top[NN],cnt;
12 vector<ii>t;
13 inline int read(){
14 int x=0,f=1;
15 char ch=getchar();
16 while(ch<'0'||ch>'9'){
17 if(ch=='-') f=-1;
18 ch=getchar();
19 }
20 while(ch>='0'&&ch<='9'){
21 x=(x<<1)+(x<<3)+(ch^48);
22 ch=getchar();
23 }
24 return x*f;
25 }
26 void write(int x){
27 if(x<0) putchar('-'), x=-x;
28 if(x>9) write(x/10);
29 putchar(x%10+'0');
30 }
31 inline void add(int a,int b){
32 to[++num]=b; nex[num]=head[a]; head[a]=num;
33 to[++num]=a; nex[num]=head[b]; head[b]=num;
34 }
35 void dfs1(int f,int s){
36 fa[s]=f; dep[s]=dep[f]+1; siz[s]=1;
37 for(int i=head[s];i;i=nex[i]){
38 int v=to[i];
39 if(v==f) continue;
40 dfs1(s,v);
41 siz[s]+=siz[v];
42 if(siz[v]>siz[son[s]]) son[s]=v;
43 }
44 }
45 void dfs2(int s,int t){
46 top[s]=t; dfn[s]=++cnt; id[cnt]=s;
47 if(!son[s]) return;
48 dfs2(son[s],t);
49 for(int i=head[s];i;i=nex[i]){
50 int v=to[i];
51 if(v!=son[s]&&v!=fa[s]) dfs2(v,v);
52 }
53 }
54 inline int LCA(int x,int y){
55 int fx=top[x],fy=top[y];
56 while(fx!=fy)
57 if(dep[fx]<dep[fy]) y=fa[fy], fy=top[y];
58 else x=fa[fx], fx=top[x];
59 return dep[x]>dep[y]?y:x;
60 }
61 inline bool check(int x,int ti){
62 for(int j=0;j<t.size();j++)
63 if(dep[x]+dep[t[j].fi]-2*dep[LCA(x,t[j].fi)]<=ti-t[j].se)
64 return 0;
65 return 1;
66 }
67 signed main(){
68 n=read(); m=read();
69 for(int i=1;i<n;i++) add(read(),read());
70 dfs1(0,1); dfs2(1,1);
71 for(int i=1;i<=m;i++){
72 opt=read(); x=read();
73 if(opt==1) if(check(x,i)) t.pb(mp(x,i));
74 if(opt==2) t.clear();
75 if(opt==3) puts(check(x,i)?"orzFsYo":"wrxcsd");
76 }
77 return 0;
78 }

T2

upd:一个链一个菊花直接把RMQ跟树剖卡废了。考虑赵sir的神仙线段树。

一个点u被v染色,要满足$dep_{u}+dep_{v}-2\times dep_{lca_{u,v}}<=now-time_{v}$,移个项可得$time_{v}+dep_{v}-2\times dep_{lca_{u,v}}<=now-dep_{u}$。

在线段树中维护等式左边的最小值,每次修改向上修改到根,查询时也跳链比较等式左右即可。清空直接打标记。

code:

  1 #include<bits/stdc++.h>
2 #define debug exit(0)
3 #define ld rt<<1
4 #define rd (rt<<1)|1
5 using namespace std;
6 const int NN=1e5+5,inf=2e9;
7 int n,m,x,to[NN<<1],nex[NN<<1],head[NN],opt,num;
8 int dep[NN],son[NN],siz[NN],dfn[NN],id[NN],fa[NN],top[NN],cnt;
9 inline int read(){
10 int x=0,f=1;
11 char ch=getchar();
12 while(ch<'0'||ch>'9'){
13 if(ch=='-') f=-1;
14 ch=getchar();
15 }
16 while(ch>='0'&&ch<='9'){
17 x=(x<<1)+(x<<3)+(ch^48);
18 ch=getchar();
19 }
20 return x*f;
21 }
22 void write(int x){
23 if(x<0) putchar('-'), x=-x;
24 if(x>9) write(x/10);
25 putchar(x%10+'0');
26 }
27 inline void add(int a,int b){
28 to[++num]=b; nex[num]=head[a]; head[a]=num;
29 to[++num]=a; nex[num]=head[b]; head[b]=num;
30 }
31 void dfs1(int f,int s){
32 fa[s]=f; dep[s]=dep[f]+1; siz[s]=1;
33 for(int i=head[s];i;i=nex[i]){
34 int v=to[i];
35 if(v==f) continue;
36 dfs1(s,v);
37 siz[s]+=siz[v];
38 if(siz[v]>siz[son[s]]) son[s]=v;
39 }
40 }
41 void dfs2(int s,int t){
42 top[s]=t; dfn[s]=++cnt; id[cnt]=s;
43 if(!son[s]) return;
44 dfs2(son[s],t);
45 for(int i=head[s];i;i=nex[i]){
46 int v=to[i];
47 if(v!=son[s]&&v!=fa[s]) dfs2(v,v);
48 }
49 }
50 struct segment_tree{
51 int l[NN<<2],r[NN<<2],mn[NN<<2],laz[NN<<2],lzc[NN<<2];
52 void pushup(int rt){
53 if(l[rt]==r[rt]) return;
54 mn[rt]=min(mn[ld],mn[rd]);
55 }
56 void pushdown(int rt){
57 if(l[rt]==r[rt]) return;
58 if(lzc[rt]){
59 mn[ld]=inf; mn[rd]=inf;
60 laz[ld]=laz[rd]=0;
61 lzc[ld]=lzc[rd]=1; lzc[rt]=0;
62 }
63 if(laz[rt]){
64 mn[ld]=min(mn[ld],laz[rt]-2*dep[id[r[ld]]]);
65 mn[rd]=min(mn[rd],laz[rt]-2*dep[id[r[rd]]]);
66 if(!laz[ld]) laz[ld]=laz[rt];
67 else laz[ld]=min(laz[ld],laz[rt]);
68 if(!laz[rd]) laz[rd]=laz[rt];
69 else laz[rd]=min(laz[rd],laz[rt]);
70 laz[rt]=0;
71 }
72 }
73 void build(int rt,int opl,int opr){
74 l[rt]=opl; r[rt]=opr; mn[rt]=inf;
75 if(opl==opr) return;
76 int mid=opl+opr>>1;
77 build(ld,opl,mid); build(rd,mid+1,opr);
78 }
79 void update(int rt,int opl,int opr,int val){
80 if(l[rt]>=opl&&r[rt]<=opr){
81 if(val!=inf){
82 mn[rt]=min(mn[rt],val-2*dep[id[r[rt]]]);
83 if(!laz[rt]) laz[rt]=val;
84 else laz[rt]=min(laz[rt],val);
85 }
86 else{ mn[rt]=inf; laz[rt]=0; lzc[rt]=1; }
87 return;
88 }
89 pushdown(rt);
90 int mid=l[rt]+r[rt]>>1;
91 if(opl<=mid) update(ld,opl,opr,val);
92 if(opr>mid) update(rd,opl,opr,val);
93 pushup(rt);
94 }
95 int query(int rt,int opl,int opr){
96 if(l[rt]>=opl&&r[rt]<=opr) return mn[rt];
97 pushdown(rt);
98 int mid=l[rt]+r[rt]>>1,ans=inf;
99 if(opl<=mid) ans=min(ans,query(ld,opl,opr));
100 if(opr>mid) ans=min(ans,query(rd,opl,opr));
101 return ans;
102 }
103 }s;
104 void UPD(int x,int val){
105 int fx=top[x];
106 val=val+dep[x];
107 while(fx!=1){
108 s.update(1,dfn[fx],dfn[x],val);
109 x=fa[fx]; fx=top[x];
110 }
111 s.update(1,1,dfn[x],val);
112 }
113 void SOL(int x,int val){
114 int fx=top[x];
115 val=val-dep[x];
116 while(fx!=1){
117 if(s.query(1,dfn[fx],dfn[x])<=val){
118 puts("wrxcsd");
119 return;
120 }
121 x=fa[fx]; fx=top[x];
122 }
123 if(s.query(1,1,dfn[x])<=val) puts("wrxcsd");
124 else puts("orzFsYo");
125 }
126 int main(){
127 n=read(); m=read();
128 for(int i=1;i<n;i++) add(read(),read());
129 dfs1(0,1); dfs2(1,1); s.build(1,1,n);
130 for(int i=1;i<=m;i++){
131 opt=read(); x=read();
132 if(opt==1) UPD(x,i);
133 if(opt==2) s.update(1,1,n,inf);
134 if(opt==3) SOL(x,i);
135 }
136 return 0;
137 }

T2线段树

T3 牛半仙的妹子序列


一眼极长上升子序列。

但不会。

于是又回顾了一遍god knows(模拟16),还是不大懂,整了挺久。但好像几乎一模一样。

把求最小权的步骤换成求方案数就完了。

code:

 1 #include<bits/stdc++.h>
2 #define debug exit(0)
3 #define int long long
4 #define ld rt<<1
5 #define rd (rt<<1)|1
6 using namespace std;
7 const int p=998244353,NN=2e5+5;
8 int n,bty[NN],ans;
9 inline int read(){
10 int x=0,f=1;
11 char ch=getchar();
12 while(ch<'0'||ch>'9'){
13 if(ch=='-') f=-1;
14 ch=getchar();
15 }
16 while(ch>='0'&&ch<='9'){
17 x=(x<<1)+(x<<3)+(ch^48);
18 ch=getchar();
19 }
20 return x*f;
21 }
22 void write(int x){
23 if(x<0) putchar('-'), x=-x;
24 if(x>9) write(x/10);
25 putchar(x%10+'0');
26 }
27 struct segment_tree{
28 int mx[NN<<2],sum[NN<<2],l[NN<<2],r[NN<<2],us[NN<<2],nxt;
29 int calc(int rt,int val){
30 if(l[rt]==r[rt]) return mx[rt]>val?sum[rt]:0;
31 if(mx[rd]<=val) return calc(ld,val);
32 return (us[ld]+calc(rd,val))%p;
33 }
34 void pushup(int rt){
35 mx[rt]=max(mx[ld],mx[rd]);
36 sum[rt]=(sum[rd]+(us[ld]=calc(ld,mx[rd])))%p;
37 }
38 void build(int rt,int opl,int opr){
39 l[rt]=opl; r[rt]=opr; mx[rt]=-1;
40 if(opl==opr) return;
41 int mid=opl+opr>>1;
42 build(ld,opl,mid);
43 build(rd,mid+1,opr);
44 }
45 void insert(int rt,int pos,int i,int val){
46 if(l[rt]==r[rt]){ sum[rt]=val; mx[rt]=i; return; }
47 int mid=l[rt]+r[rt]>>1;
48 if(pos<=mid) insert(ld,pos,i,val);
49 else insert(rd,pos,i,val);
50 pushup(rt);
51 }
52 int query(int rt,int opl,int opr){
53 if(l[rt]>=opl&&r[rt]<=opr){
54 int ans=calc(rt,nxt);
55 nxt=max(nxt,mx[rt]);
56 return ans;
57 }
58 int mid=l[rt]+r[rt]>>1,ans=0;
59 if(opr>mid) (ans+=query(rd,opl,opr))%=p;
60 if(opl<=mid) (ans+=query(ld,opl,opr))%=p;
61 return ans;
62 }
63 }s;
64 signed main(){
65 n=read();
66 for(int i=1;i<=n;i++) bty[i]=read();
67 ++n; bty[n]=n; s.build(1,0,n); s.insert(1,0,0,0);
68 for(int i=1;i<=n;i++){
69 s.nxt=-1;
70 int tmp=s.query(1,0,bty[i]-1)%p;
71 if(!tmp) tmp=1;
72 s.insert(1,bty[i],i,tmp);
73 if(i==n) write(tmp), putchar('\n');
74 }
75 return 0;
76 }

T3

2021.7.29考试总结[NOIP模拟27]的更多相关文章

  1. 2021.6.29考试总结[NOIP模拟10]

    T1 入阵曲 二位前缀和暴力n4可以拿60. 观察到维护前缀和时模k意义下余数一样的前缀和相减后一定被k整除,前缀和维护模数,n2枚举行数,n枚举列, 开一个桶记录模数出现个数,每枚举到该模数就加上它 ...

  2. 7.29考试总结(NOIP模拟27)[牛半仙的妹子图·Tree·序列]

    前言 从思路上来讲是比较成功的,从分数上就比较令人失望了. 考场上是想到了前两个题的正解思路,其实最后一个题是半个原题,只可惜是我看不懂题... 这波呀,这波又是 语文素养限制OI水平.. 改题的时候 ...

  3. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  4. 2021.8.3考试总结[NOIP模拟29]

    T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...

  5. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  6. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  7. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  8. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  9. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

随机推荐

  1. RocketMQ详解(四)核心设计原理

    专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...

  2. 机器学习——EM算法

    1 数学基础 在实际中,最小化的函数有几个极值,所以最优化算法得出的极值不确实是否为全局的极值,对于一些特殊的函数,凸函数与凹函数,任何局部极值也是全局极致,因此如果目标函数是凸的或凹的,那么优化算法 ...

  3. 3.15学习总结(Python爬取网站数据并存入数据库)

    在官网上下载了Python和PyCharm,并在网上简单的学习了爬虫的相关知识. 结对开发的第一阶段要求: 网上爬取最新疫情数据,并存入到MySql数据库中 在可视化显示数据详细信息 项目代码: im ...

  4. python函数模块

    python函数模块 学习完本篇,你将会深入掌握 函数相关知识 1.函数定义 2.函数如何调用 3.递归函数以及匿名函数使用 模块相关知识 1.模块如何导入调用 2.函数调用顺序 函数定义 函数代码块 ...

  5. Java中的三大特性:封装、继承、多态

    封装: 概念:封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问,适当的封装可以让代码更容易理解与维护,也加强了代码的安全性. 原则:将属性隐藏起来,若需要访问某个属性,提供公共方法对 ...

  6. Groovy系列(4)- Groovy集合操作

    Groovy集合操作 Lists List 字面值 您可以按如下所示创建列表. 请注意,[]是空列表表达式 def list = [5, 6, 7, 8] assert list.get(2) == ...

  7. python读取文件编码转换问题

    encode(编码)   decode(解码)   encoding(编码格式) #-*- coding:utf-8 -*- import chardet #用于查看编码 with open(&quo ...

  8. GUI编程笔记

    GUI编程 告诉大家该怎么学? 这是什么? 它怎么玩? 该如何去我们平时运用? 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1.简介 GUi的核心技术:Sw ...

  9. 测试开发【提测平台】分享11-Python实现邮件发送的两种方法实践

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 按照开发安排,本篇本应该是关于提测页面的搜索和显示实现,怕相似内容疲劳,这期改下内容顺序,将邮件服务的相关的提前,在之前的产品需求和原型中 ...

  10. P4389-付公主的背包【生成函数,多项式exp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4389 题目大意 \(n\)种物品,第\(i\)种大小为\(v_i\),数量无限.对于每个\(s\in[1,m]\ ...