Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园
以下内容未验证,有错请指正...
设块大小为T,则块数为$\frac{n}{T}$
将询问分为$(\frac{n}{T})^2$块(按照左端点所在块和右端点所在块分块),同块内按时间从小到大依次处理
1.左/右端点块内移动总代价:$q*T$
2.时间的移动总代价:$(\frac{n}{T})^2*n$
总复杂度:$q*T+\frac{n^3}{T^2}$
好吧,事实上一般不会这么写。。。
一般只需要把询问按三个关键字(优先级:左端点所在块>右端点所在块>时间)排序,然后在任意两个询问间转移
一般的写法还要:
1.左端点块间移动代价:$n$
2.右端点块间移动代价:$\frac{n}{T}*n$
事实上是不影响的。。。
最优块大小?还真不会算,可以确定的是当$T=n^\frac{2}{3}$时,最终复杂度是(设n与q同阶)$n^{\frac{5}{3}}$
https://www.luogu.org/problemnew/show/CF940F
模板,跑一下就行了。。。
比较特别的是,要求的那个mex一定不会超过sqrt(n)级别(如果mex=k,说明查询的区间内至少有1+2+3+..+(k-1)=k*(k-1)/2个数),可以直接暴力跑(常数要小一点的话,就瞎维护一下(?讲不清楚啊))
upd:突然发现用以下的方法维护答案,复杂度好像不太对(n^(5/3)*sqrt(n)>n^2)?可能还是每次暴力找答案好?
错误记录:(都是一些很容易犯但是极其难发现的错误,要小心了)
1.题面有点绕,搞混了"数的出现次数"和"数的出现次数的出现次数"
2.75,83行成了"del(...);ins(...)";if没起到正确作用
3.最后输出的时候只枚举编号到了n,没有枚举到qq
4.修改时间时,没有判要del的是否本来就在里面(如75行的if),如果本来不在里面那么不要del也不要ins
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N=;
struct C
{
int p,a,b,t;//p位置从a改为b
}c[N];
int nc;
struct Q
{
int l,r,t,num;
}q[N];
int nq;
int nl,nr,nt,pc;
const int sz=;
int bl[N];
int ans[N];
int a[N],b[N];
bool c1(const Q &a,const Q &b)
{
return bl[a.l]<bl[b.l]
||(bl[a.l]==bl[b.l]&&bl[a.r]<bl[b.r])
||(bl[a.l]==bl[b.l]&&bl[a.r]==bl[b.r]&&a.t<b.t);
}
int n1[],n2[];
int nans;
int qn[N],cn[N];
int tt[];
map<int,int> ma;
void decn2(int x)
{
if(!x) return;
n2[x]--;
if(n2[x]==)
{
if(nans>x) nans=x;
}
}
void incn2(int x)
{
if(!x) return;
n2[x]++;
if(n2[x]==)
{
if(nans==x)
{
while(n2[nans]) nans++;
}
}
}
void ins(int x)
{
decn2(n1[x]);n1[x]++;incn2(n1[x]);
}
void del(int x)
{
decn2(n1[x]);n1[x]--;incn2(n1[x]);
}
void inctime()
{
while(pc+<=nc&&c[pc+].t<=nt)
{
pc++;
if(nl<=c[pc].p&&c[pc].p<=nr) del(c[pc].a),ins(c[pc].b);
a[c[pc].p]=c[pc].b;
}
}
void dectime()
{
while(pc>=&&c[pc].t>nt)
{
if(nl<=c[pc].p&&c[pc].p<=nr) del(c[pc].b),ins(c[pc].a);
a[c[pc].p]=c[pc].a;
pc--;
}
}
int n,qq;
int main()
{
int i,idx,l,r,p,x;
scanf("%d%d",&n,&qq);
for(i=;i<=n;i++) bl[i]=(i-)/sz;
for(i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i],tt[++tt[]]=a[i];
for(i=;i<=qq;i++)
{
scanf("%d",&idx);
if(idx==)
{
scanf("%d%d",&l,&r);
++nq;q[nq].l=l;q[nq].r=r;q[nq].t=nt;q[nq].num=i;
qn[i]=nq;
}
else
{
scanf("%d%d",&p,&x);tt[++tt[]]=x;
++nc;c[nc].p=p;c[nc].a=a[p];c[nc].b=x;
a[p]=x;
++nt;c[nc].t=nt;
cn[i]=nc;
}
}
for(i=;i<=n;i++) a[i]=b[i];
sort(tt+,tt+tt[]+);tt[]=unique(tt+,tt+tt[]+)-tt-;
for(i=;i<=tt[];i++) ma[tt[i]]=i;
for(i=;i<=n;i++) a[i]=ma[a[i]];
for(i=;i<=qq;i++)
if(cn[i])
{
c[cn[i]].a=ma[c[cn[i]].a];
c[cn[i]].b=ma[c[cn[i]].b];
}
/*
{
puts("Q");
for(i=1;i<=nq;i++)
{
printf("%d %d %d %d\n",q[i].l,q[i].r,q[i].t,q[i].num);
}
puts("C");
for(i=1;i<=nc;i++)
{
printf("%d %d %d %d\n",c[i].p,c[i].a,c[i].b,c[i].t);
}
}
*/
sort(q+,q+nq+,c1);
nl=;nr=;nt=;nans=;pc=;
for(i=;i<=nq;i++)
{
//printf("i%d %d\n",i,q[i].num);
while(nl>q[i].l) nl--,ins(a[nl]);
while(nr<q[i].r) nr++,ins(a[nr]);
while(nl<q[i].l) del(a[nl]),nl++;
while(nr>q[i].r) del(a[nr]),nr--;
if(nt<q[i].t) nt=q[i].t,inctime();
if(nt>q[i].t) nt=q[i].t,dectime();
ans[q[i].num]=nans;
}
for(i=;i<=qq;i++)
if(qn[i])
printf("%d\n",ans[i]);
return ;
}
https://www.luogu.org/problemnew/show/P4074
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const ll N=;
struct E
{
ll to,nxt;
}e[N<<];
ll f1[N],ne;
ll n,m,qq;
ll v[N],w[N],a[N],cc2[N];
struct C
{
ll p,a,b;
}c[N];
ll nc;
struct Q
{
ll a,b,t,num;
}q[N];
ll nq;
ll cn[N],qn[N];
ll nl,nr,nt,nans,pc;
bool vis[N];
const ll sz=;
ll p[N<<],pl[N];
namespace LCA
{
ll anc[N][],l2n=,d[N];
void dfs(ll u,ll fa)
{
p[++p[]]=u;pl[u]=p[];
anc[u][]=fa;d[u]=d[fa]+;
for(ll i=;i<=l2n;i++)
anc[u][i]=anc[anc[u][i-]][i-];
for(ll k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
dfs(e[k].to,u);
p[++p[]]=u;
}
ll lft[];
void init()
{
ll i;
lft[]=;
for(i=;i<;i++) lft[i]=lft[i-]<<;
}
ll lca(ll a,ll b)
{
if(d[a]<d[b]) swap(a,b);
ll i,t=d[a]-d[b];
for(i=;t;t>>=,i++)
if(t&)
a=anc[a][i];
if(a==b) return a;
for(i=l2n;i>=;i--)
if(anc[a][i]!=anc[b][i])
{
a=anc[a][i];
b=anc[b][i];
}
return anc[a][];
}
}
using LCA::lca;
ll bl[N<<];
bool c1(const Q &a,const Q &b)
{
return bl[a.a]<bl[b.a]
||(bl[a.a]==bl[b.a]&&bl[a.b]<bl[b.b])
||(bl[a.a]==bl[b.a]&&bl[a.b]==bl[b.b]&&a.t<b.t);
}
ll ans[N];
ll nn[];
void change(ll x)
{
if(vis[x])
{
nans-=v[a[x]]*w[nn[a[x]]];
nn[a[x]]--;
}
else
{
nn[a[x]]++;
nans+=v[a[x]]*w[nn[a[x]]];
}
vis[x]^=;
}
void inctime()
{
while(pc+<=nc&&pc+<=nt)
{
pc++;
bool fl=vis[c[pc].p];
if(fl) change(c[pc].p);
a[c[pc].p]=c[pc].b;
if(fl) change(c[pc].p);
}
}
void dectime()
{
while(pc>=&&pc>nt)
{
bool fl=vis[c[pc].p];
if(fl) change(c[pc].p);
a[c[pc].p]=c[pc].a;
if(fl) change(c[pc].p);
pc--;
}
}
int main()
{
LCA::init();
ll i,x,y,idx,l;
scanf("%lld%lld%lld",&n,&m,&qq);
for(i=;i<=m;i++) scanf("%lld",&v[i]);
for(i=;i<=n;i++) scanf("%lld",&w[i]);
for(i=;i<n;i++)
{
scanf("%lld%lld",&x,&y);
e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
}
for(i=;i<=n;i++) scanf("%lld",&a[i]),cc2[i]=a[i];
for(i=;i<=qq;i++)
{
scanf("%lld%lld%lld",&idx,&x,&y);
if(idx==)
{
++nc;
c[nc].p=x;c[nc].a=a[x];c[nc].b=y;a[x]=y;
cn[i]=nc;
}
else
{
++nq;
q[nq].a=x;q[nq].b=y;q[nq].t=nc;q[nq].num=i;
qn[i]=nq;
}
}
LCA::dfs(,);
for(i=;i<=nq;i++)
{
q[i].a=pl[q[i].a];
q[i].b=pl[q[i].b];
if(q[i].a>q[i].b) swap(q[i].a,q[i].b);
}
/*
for(i=1;i<=nc;i++)
{
c[i].p=pl[c[i].p];
}
*/
for(i=;i<=p[];i++) bl[i]=(i-)/sz;
sort(q+,q+nq+,c1);
for(i=;i<=n;i++) a[i]=cc2[i];
nl=;nr=;nt=;nans=;pc=;
for(i=;i<=nq;i++)
{
while(nl>q[i].a) --nl,change(p[nl]);
while(nr<q[i].b) ++nr,change(p[nr]);
while(nl<q[i].a) change(p[nl]),++nl;
while(nr>q[i].b) change(p[nr]),--nr;
if(nt<q[i].t) nt=q[i].t,inctime();
if(nt>q[i].t) nt=q[i].t,dectime();
l=lca(p[q[i].a],p[q[i].b]);
bool fl1=vis[p[q[i].a]],fl2=vis[p[q[i].b]];
bool fl3=vis[l];
if(!fl1) change(p[q[i].a]);
if(!fl2) change(p[q[i].b]);
if(!fl3) change(l);
ans[q[i].num]=nans;
if(!fl1) change(p[q[i].a]);
if(!fl2) change(p[q[i].b]);
if(!fl3) change(l);
}
for(i=;i<=qq;i++)
if(qn[i])
printf("%lld\n",ans[i]);
return ;
}
Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园的更多相关文章
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- Machine Learning CodeForces - 940F (带修改的莫队)
You come home and fell some unpleasant smell. Where is it coming from? You are given an array a. You ...
- Machine Learning(CF940F+带修改莫队)
题目链接:http://codeforces.com/problemset/problem/940/F 题目: 题意:求次数的mex,mex的含义为某个集合(如{1,2,4,5})第一个为出现的非负数 ...
- CF940F Machine Learning(带修莫队)
首先显然应该把数组离散化,然后发现是个带修莫队裸题,但是求mex比较讨厌,怎么办?其实可以这样求:记录每个数出现的次数,以及出现次数的出现次数.至于求mex,直接暴力扫最小的出现次数的出现次数为0的正 ...
- Codeforces 1476G - Minimum Difference(带修莫队+根号平衡)
Codeforces 题目传送门 & 洛谷题目传送门 震惊!我竟然独立切掉了这道 *3100 的题! 虽然此题难度的确虚高,感觉真实评分也就 2800~2900 罢.但感觉还是挺有成就感的( ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】
题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...
- BZOJ2120 数颜色 莫队 带修莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...
- BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html 题目传送门 - BZOJ3052 题目传送门 - UOJ#58 题意 给定一棵树,有 ...
随机推荐
- spring类扫描注入-----类扫描的注解解析器
通过类扫描注入到容器中,这种方式,在实际开发中还是很常用的,可以看下自己的配置文件,就会发现,自己公司的项目,搞不好就是这么注入的. 起码,我发现我公司的项目就是这么干的. 下面来演示一下简单的例子: ...
- 程序员代码面试指南:IT名企算法与数据结构题目最优解
第1章栈和队列 1设计一个有getMin功能的栈(士★☆☆☆) 1由两个栈组成的队列(尉★★☆☆) 5如何仅用递归函数和栈操作逆序一个栈(尉★★☆☆) 8猫狗队列(士★☆☆☆)10用一个栈实现另一 ...
- 极光API推送 (v3 版本)
Push API v3 这是 Push API 最近的版本. 相比于 API v2 版本,v3 版本的改进为: 完全基于 https,不再提供 http 访问: 使用 HTTP Basic Authe ...
- Java网络编程InetAddress类
InetAddress用来代表IP地址.一个InetAdress的对象就代表着一个IP地址, getByName(String host):在给定主机名的情况下确定主机的 IP 地址,主机名可以是机器 ...
- darknet源码学习
darknet是一个较为轻型的完全基于C与CUDA的开源深度学习框架,其主要特点就是容易安装,没有任何依赖项(OpenCV都可以不用),移植性非常好,支持CPU与GPU两种计算方式.1.test源码( ...
- 给YUI Compressor添加右键命令,完成快捷压缩
YUI Compressor默认不带右键安装功能 YUI Compressor非常好用,特别是JS的混淆是众多JS Coding的最爱.可惜官网提供的版本都不具备右键功能,每次压缩都要cmd输入一些命 ...
- Linux串口通信中一种接收不到数据的问题的解决
转载来源:嵌入式系统之初学者点滴 (百度空间) 原文 在这篇文章()中,实现了Linux环境下的串口读写操作,程序也运行成功了.但是再进一步测试时发现,如果开机之后直接如上文中所说,分别运行读程序和写 ...
- 使用IIS Express调试网站的方法
如果不想安装IIS,可以直接使用IIS Express来运行网站. vs2012: 新建个文档,拷贝下面代码 taskkill /F /IM "WebDev.WebServer40.EXE& ...
- js中实现子页面向父页面中赋值
(方法一) 父页面: <input id="input1" type="text"/> <a href="javascript:wi ...
- 微信小程序开发之实现https
1:使用自签名的免费ssl证书实现:http://jingyan.baidu.com/article/a948d6515d3e850a2dcd2ee6.html 2:迅雷云购 ...