APIO2019简要题解
Luogu P5444 [APIO2019]奇怪装置
看到这种题,我们肯定会想到\((x,y)\)一定有循环
我们要找到循环节的长度
推一下发现\(x\)的循环节长为\(\frac{AB}{B+1}\)。等一下,\(t\)是整数,所以循环节长为\(\frac{AB}{GCD(A,B+1)}\)
\(y\)的循环节长为\(B\)
所以\((x,y)\)的循环节长为\(lcm(\frac{AB}{GCD(A,B+1)},B)=\frac{AB}{GCD(A,B+1)}\)
对每个时间段对循环节长取模进行区间覆盖即可
代码(用了__int128)
#include <bits/stdc++.h>
#define N 1000005
#define ll long long
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline ll read()
{
register ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register ll x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline ll Max(register ll a,register ll b)
{
return a>b?a:b;
}
vector<pair<ll,ll> >v;
int n;
ll A,B;
int main()
{
n=read(),A=read(),B=read();
__int128 k=(__int128)A*B/__gcd(A,B+1);
for(register int i=1;i<=n;++i)
{
ll l=read(),r=read();
if(r-l+1>=k)
{
write((ll)k);
return 0;
}
else
{
l%=k;
r%=k;
if(l<=r)
v.push_back(make_pair(l,r));
else
{
v.push_back(make_pair(l,(ll)k-1));
v.push_back(make_pair(0ll,r));
}
}
}
sort(v.begin(),v.end());
ll l=0,r=-1,ans=0;
for(register int i=0;i<v.size();++i)
{
if(v[i].first<=r)
r=Max(r,v[i].second);
else
ans+=r-l+1,l=v[i].first,r=v[i].second;
}
ans+=r-l+1;
write(ans);
return 0;
}
Luogu P5443 [APIO2019]桥梁
我们先考虑不带修改怎么做——珂以贪心地将桥的承受重量和车的重量从大到小排序,从大往小扫描车,用并查集维护边和答案
考虑有修改操作,我们珂以使用分块,设块的大小为\(blk\)
那么每个块中的修改操作不超过\(\frac{q}{blk}\)个
我们先把没有修改的边和所有询问的点像不带修一样从大到小排序,从大往小扫描车,对于每辆车,单独加入被修改的一些边,加入后通过并查集回退来撤销,所以并查集不能路径压缩,要按秩合并,处理完询问后要将原图更新,但是不能直接快排,新边要和原来已经有序的边进行合并排序,这个单块复杂度是\(O(m\alpha+\frac{n^2}{blk^2}\alpha+m)\)
我blk取的是\(\sqrt{n\log n}\),所以总复杂度是\(O(m \sqrt{n\log n} \alpha)\)
#include <bits/stdc++.h>
#define M 100005
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
struct edge{
int u,v,w,i;
}e[M],E[M],tmp[M];
bool operator < (edge a,edge b)
{
return a.w!=b.w?a.w>b.w:a.i<b.i;
}
struct query{
int id,t,b,r;
}q[M],tmp1[M],tmp2[M];
inline bool cmp(register query a,register query b)
{
return a.b>b.b;
}
int fa[M],sz[M],top;
struct mste{
int u,v;
}sta[M];
inline int getfa(register int x)
{
return x==fa[x]?x:getfa(fa[x]);
}
inline void Merge(register int u,register int v)
{
u=getfa(u);
v=getfa(v);
if(u==v)
return;
if(sz[u]<sz[v])
u^=v^=u^=v;
fa[v]=u;
sz[u]+=sz[v];
sta[++top]=(mste){u,v};
}
inline void cancel()
{
int u=sta[top].u,v=sta[top].v;
--top;
fa[v]=v;
sz[u]-=sz[v];
}
int n,m,Q,blk,tot,t1,t2,ans[M];
int vis[M],id[M],d[M];
inline void work()
{
for(register int i=1;i<=m;++i)
vis[i]=0;
for(register int i=1;i<=n;++i)
fa[i]=i,sz[i]=1;
t1=t2=top=0;
for(register int i=1;i<=tot;++i)
if(q[i].t==1)
vis[q[i].b]=1,tmp1[++t1]=q[i];
else
tmp2[++t2]=q[i];
sort(tmp2+1,tmp2+1+t2,cmp);
for(register int i=1;i<=m;++i)
id[e[i].i]=i;
for(register int i=1,p=1;i<=t2;++i)
{
while(p<=m&&e[p].w>=tmp2[i].b)
{
if(!vis[e[p].i])
Merge(e[p].u,e[p].v);
++p;
}
int lastop=top;
for(register int j=1;j<=t1;++j)
d[tmp1[j].b]=e[id[tmp1[j].b]].w;
for(register int j=1;j<=t1;++j)
if(tmp1[j].id<tmp2[i].id)
d[tmp1[j].b]=tmp1[j].r;
for(register int j=1;j<=t1;++j)
if(d[tmp1[j].b]>=tmp2[i].b)
Merge(e[id[tmp1[j].b]].u,e[id[tmp1[j].b]].v);
ans[tmp2[i].id]=sz[getfa(tmp2[i].r)];
while(top>lastop)
cancel();
}
for(register int i=1;i<=t1;++i)
e[id[tmp1[i].b]].w=tmp1[i].r;
t1=t2=0;
for(register int i=1;i<=m;++i)
if(vis[e[i].i])
E[++t1]=e[i];
else
e[++t2]=e[i];
sort(E+1,E+1+t1);
merge(E+1,E+1+t1,e+1,e+1+t2,tmp+1);
for(register int i=1;i<=m;++i)
e[i]=tmp[i];
}
int main()
{
n=read(),m=read();
blk=sqrt(n*log2(n));
for(register int i=1;i<=m;++i)
e[i].u=read(),e[i].v=read(),e[i].w=read(),e[i].i=i;
sort(e+1,e+1+m);
Q=read();
for(register int i=1;i<=Q;++i)
{
int t=read();
if(t==1)
{
int b=read(),r=read();
q[++tot]=(query){i,t,b,r};
}
else
{
int s=read(),w=read();
q[++tot]=(query){i,t,w,s};
}
if(tot==blk)
work(),tot=0;
}
if(tot)
work();
for(register int i=1;i<=Q;++i)
if(ans[i])
write(ans[i]),puts("");
return 0;
}
Luogu P5445 [APIO2019]路灯
这道题珂以暴力数据结构
我们用树状数组套主席树
每个点开个主席树,每个位置表示假如之后再也不修改,能到那个位置的次数(包括修改前的次数)
树状数组维护主席树的和
这样就珂以方便的进行差分
上代码(不想说了,自己看,简单易懂)
注意主席树中存的是之后再也不修改的答案数,要根据情况判断是否要减去一些
#include <bits/stdc++.h>
#define N 300005
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
int n,q,c[N];
set<int> st;
set<int>::iterator now,pre,nxt;
struct node{
int ls,rs,val;
}tr[N*40];
int tot,rt[N];
inline void change(register int &x,register int l,register int r,register int pos,register int val)
{
if(!x)
x=++tot;
tr[x].val+=val;
if(l==r)
return;
int mid=l+r>>1;
if(pos<=mid)
change(tr[x].ls,l,mid,pos,val);
else
change(tr[x].rs,mid+1,r,pos,val);
}
inline int querys(register int x,register int l,register int r,register int L,register int R)
{
if(!x)
return 0;
if(L<=l&&r<=R)
return tr[x].val;
int mid=l+r>>1,res=0;
if(L<=mid)
res+=querys(tr[x].ls,l,mid,L,R);
if(R>mid)
res+=querys(tr[x].rs,mid+1,r,L,R);
return res;
}
inline int lowbit(register int x)
{
return x&(-x);
}
inline void modify(register int x,register int pos,register int val)
{
while(x<=n+1)
change(rt[x],1,n+1,pos,val),x+=lowbit(x);
}
inline int query(register int x,register int pos)
{
int res=0;
while(x)
res+=querys(rt[x],1,n+1,1,pos),x-=lowbit(x);
return res;
}
int main()
{
n=read(),q=read();
for(register int i=1;i<=n;++i)
{
char ch=getchar();
while(ch!='0'&&ch!='1')
ch=getchar();
c[i]=ch-'0';
}
st.insert(0),st.insert(n+1);
modify(1,1,q);
for(register int i=1,j=0;i<=n;++i)
{
if(c[i]==1)
continue;
st.insert(i);
modify(j+1,i+1,-q);
modify(i+1,i+1,q);
j=i;
}
while(q--)
{
char ch=getchar();
while(ch!='t'&&ch!='q')
ch=getchar();
if(ch=='t')
{
int x=read(),v=(c[x]==0)?1:-1;
if(c[x]==1)
st.insert(x);
now=st.find(x);
pre=nxt=now;
--pre,++nxt;
modify(*pre+1,x+1,q*v);
modify(x+1,x+1,-q*v);
if(*nxt!=n+1)
{
modify(*pre+1,*nxt+1,-q*v);
modify(x+1,*nxt+1,q*v);
}
if(c[x]==0)
st.erase(x);
c[x]^=1;
}
else
{
int a=read(),b=read();
write(query(a,b)-q*(st.lower_bound(a)==st.lower_bound(b))),puts("");
}
}
return 0;
}
APIO2019简要题解的更多相关文章
- Noip 2014酱油记+简要题解
好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...
- Tsinghua 2018 DSA PA2简要题解
反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
- JXOI2018简要题解
JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...
- BJOI2018简要题解
BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...
- CQOI2018简要题解
CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...
- AtCoder ExaWizards 2019 简要题解
AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...
- Comet OJ - Contest #2 简要题解
Comet OJ - Contest #2 简要题解 cometoj A 模拟,复杂度是对数级的. code B 易知\(p\in[l,r]\),且最终的利润关于\(p\)的表达式为\(\frac{( ...
随机推荐
- FPM 1.1正式版 Search & List
前面写的FPM都是自己练习用的.直到自己正式用了一个,才发现一些小问题.feeder class写在一起和分开写有好有坏,这里就不说了. 自己做了个小的查询报表如下: 现在来按SAP官方的做法来重新做 ...
- OpenInstall实现APP无邀请码推广
1.登录OpenInstall网站,这里会为你创建一个AppKey,而这个东西在web页面会用到. 2.在推广页面中加入推广下载. <script type="text/javascr ...
- Linux的DNS实现负载均衡及泛域名部署
DNS负载均衡技术的实现原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到 ...
- TF-IDF算法介绍及实现
目录 1.TF-IDF算法介绍 (1)TF是词频(Term Frequency) (2) IDF是逆向文件频率(Inverse Document Frequency) (3)TF-IDF实际上是:TF ...
- HDU 1240 Asteroids! 题解
Asteroids! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 1 NLP学习大纲
一.自然语言处理概述 1)自然语言处理:利用计算机为工具,对书面实行或者口头形式进行各种各样的处理和加工的技术,是研究人与人交际中以及人与计算机交际中的演员问题的一门学科,是人工智能的主要内容. 2) ...
- 《Pro Continuous Delivery With Jenkins 2.0》随书笔记
今天同时看完<Pro Continuous Delivery With Jenkins 2.0>, 这书与工作关系很大,但也是快速翻翻. 本书着重点jenkins高可用环境搭建,与gith ...
- Scrapy笔记05- Item详解
Scrapy笔记05- Item详解 Item是保存结构数据的地方,Scrapy可以将解析结果以字典形式返回,但是Python中字典缺少结构,在大型爬虫系统中很不方便. Item提供了类字典的API, ...
- Visual Studio调试XSLT
Visual Studio是一个很大的工具.很容易遗漏一些有用的特性.希望XSLT调试器不会错过.在下面,您可以看到调试器正在运行,因为xslt转换正在应用于某些XML.(请原谅我在示例中使用的毫无意 ...
- css3有哪些新特性?
新选择器,属性选择器.伪类选择器.层次选择器... 圆角属性border-radius font-face加载服务器端的字体 多列布局column 阴影shadow 弹性盒flex 过渡transit ...