A - CF538G Berserk Robot

Sol

将原题中的坐标(x,y)(x,y)(x,y)变成(x+y,x−y)(x+y,x-y)(x+y,x−y),原题的行走一步改成(1,1),(1,−1),(−1,1),(−1,−1)(1,1),(1,-1),(-1,1),(-1,-1)(1,1),(1,−1),(−1,1),(−1,−1)。这样与原来的问题是等价的,并且横纵坐标变得独立了。

单独对每一维考虑。设走完这lll步坐标的变化量为dxdxdx。

如果有两个tit_iti​模lll的余数相同,就可以解出dxdxdx,然后进行构造。

否则将已知的点将timodlt_i \bmod lti​modl排序,相邻的两个算一下它们对dxdxdx的限制。

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#define db long double
#define PB push_back
#define ll long long
using namespace std;
template <class T>
inline void rd(T &x) {x=0; char c=getchar(); int f=1;while(!isdigit(c)){if(c=='-')f=-1; c=getchar();}while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f;
}
int curtest;
void FAIL() { printf("NO"); exit(0); }
ll Abs(ll x) { return x>0?x:-x; }
db eps=1e-20;
int dcmp(db x) { return x>-eps?(x>eps):-1; }
const int N=2e6+10;
vector<int> pos;
struct node { ll t,x,y; }v[N];
ll val[N],ti[N];
int vis[N];
int m,n;
db lb,rb;
vector<char> S;
void modify(int p,ll x,ll delt) {if(Abs((delt*m+p)%2)^Abs(x%2)) FAIL();if(delt==0) return;ll l=-p-x,r=p-x; db dt=-delt;if(dt>0) lb=max(lb,l/dt),rb=min(rb,r/dt);else lb=max(lb,r/dt),rb=min(rb,l/dt);
}
void sol(vector<int> &ans) {lb=-m,rb=m;for(int i=0;i+1<pos.size();++i) {if(i+2==pos.size()) modify(m-pos[i],-val[pos[i]],-ti[pos[i]]-1);else modify(pos[i+1]-pos[i],val[pos[i+1]]-val[pos[i]],ti[pos[i+1]]-ti[pos[i]]);}ll dx=floor(rb);if(Abs(dx%2)^(m%2)) dx--;if(dcmp(dx-lb)<0) FAIL();for(int i=0;i+1<pos.size();++i) {int l=pos[i],r=pos[i+1],len=r-l;ll x=(r==m?dx:val[r])-val[l]-(ti[r]-ti[l])*dx;int d=x>0?1:-1;x=Abs(x); len-=x;while(x) x--,ans.PB(d);if(len<0||(len&1)) FAIL();while(len) ans.PB(1),ans.PB(-1),len-=2;}
}ll dx,dy;
void solve(int l,int r,ll x,ll y,ll t) {x-=t*dx,y-=t*dy;char xx=x>0?'R':'L';char yy=y>0?'U':'D';x=Abs(x),y=Abs(y);while(x--) S.PB(xx),r--;while(y--) S.PB(yy),r--;if(((r-l)&1)||r-l<0) FAIL();while(r-l) S.PB('U'),S.PB('D'),r-=2;
}vector<int> ax,ay;
int main() {rd(n),rd(m);int flg=0;vis[0]=1,v[0].x=v[0].y=v[0].t=0;for(int i=1;i<=n;++i) {node A;rd(A.t),rd(A.x),rd(A.y);int p=A.t%m;A.t/=m;if(vis[p]) {if(A.t==v[p].t) {if(A.x!=v[p].x||A.y!=v[p].y) FAIL();continue;}ll dt=A.t-v[p].t;if(flg) {if(v[p].x+dt*dx==A.x&&v[p].y+dt*dy==A.y) continue;else FAIL();}dx=A.x-v[p].x,dy=A.y-v[p].y;if(dx%dt||dy%dt) FAIL();dx/=dt,dy/=dt;flg=1;}else v[p]=A,vis[p]=1;}if(flg) {int p1=0,p2;while(true) {p2=p1+1;while(!vis[p2]&&p2<m) p2++;if(p2>=m) break;solve(p1,p2,v[p2].x-v[p1].x,v[p2].y-v[p1].y,v[p2].t-v[p1].t);p1=p2;}solve(p1,m,dx-v[p1].x,dy-v[p1].y,-v[p1].t);for(int i=0;i<S.size();++i) putchar(S[i]);}else {for(int i=0;i<m;++i) if(vis[i]) ti[i]=v[i].t,pos.PB(i);pos.PB(m),ti[m]=0;for(int i=0;i<m;++i) if(vis[i]) val[i]=v[i].x+v[i].y;sol(ax);for(int i=0;i<m;++i) if(vis[i]) val[i]=v[i].x-v[i].y;sol(ay);for(int i=0;i<m;++i) {if(ax[i]==ay[i]) putchar(ax[i]>0?'R':'L');else putchar(ax[i]>0?'U':'D');}}return 0;
}

B - CF674D Bearish Fanpages

Sol

对每个点维护它的所有儿子对它的贡献的和,这样可以在O(1)O(1)O(1)的时间完成修改,在O(1)O(1)O(1)的时间完成对某个点价值的查询。

维护全局最大最小值:对每个点xxx维护一个multiset,里面存所有儿子的(这个儿子的价值-xxx对儿子的贡献),然后将multiset中的最大的和最小的加上xxx的贡献放入一个全局的multiset。这样修改操作jiang可以在O(log⁡n)O(\log n)O(logn)的时间内完成。

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#define ll long long
using namespace std;
template <class T>
inline void rd(T &x) {x=0; char c=getchar(); int f=1;while(!isdigit(c)){if(c=='-')f=-1; c=getchar();}while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f;
}
const int N=1e5+10;
int du[N],fa[N],n;
ll ans[N],ti[N];
multiset<ll> s[N],que;
int tim,vis[N];
inline ll cot(int x) { return ti[x]/(du[x]+1); }
inline ll get(int x) { return ans[x]+(ti[x]-cot(x)*du[x]); }
inline ll getans(int x) { return cot(fa[x])+get(x); }
void Ins(int x) { if(vis[x]==tim) return; vis[x]=tim; if(!s[x].empty()) que.insert(cot(x)+(*s[x].rbegin())),que.insert(cot(x)+(*s[x].begin())); }
void Del(int x) { if(vis[x]==tim) return; vis[x]=tim; if(!s[x].empty()) que.erase(que.find(cot(x)+(*s[x].rbegin()))),que.erase(que.find((cot(x)+(*s[x].begin())))); }
void link(int x,int f) {int ff=fa[f];tim++,Del(x),Del(f),Del(ff),Del(fa[ff]);if(ff) {if(fa[ff]) s[fa[ff]].erase(s[fa[ff]].find(get(ff)));s[ff].erase(s[ff].find(get(f)));ans[ff]-=cot(f);}fa[x]=f,du[x]++,du[f]++;ans[f]+=cot(x);s[f].insert(get(x));if(ff) {ans[ff]+=cot(f);s[ff].insert(get(f));if(fa[ff]) s[fa[ff]].insert(get(ff));}tim++,Ins(x),Ins(f),Ins(ff),Ins(fa[ff]);
}
void cut(int x) {int f=fa[x],ff=fa[f];tim++,Del(x),Del(f),Del(ff),Del(fa[ff]);if(ff) {if(fa[ff]) s[fa[ff]].erase(s[fa[ff]].find(get(ff)));s[ff].erase(s[ff].find(get(f)));ans[ff]-=cot(f);}s[f].erase(s[f].find(get(x)));ans[f]-=cot(x);du[x]--,du[fa[x]]--,fa[x]=0;if(ff) {ans[ff]+=cot(f);s[ff].insert(get(f));if(fa[ff]) s[fa[ff]].insert(get(ff));}tim++,Ins(x),Ins(f),Ins(ff),Ins(fa[ff]);
}
int main() {int q; rd(n),rd(q);for(int i=1;i<=n;++i) rd(ti[i]);for(int f,i=1;i<=n;++i) rd(f),link(i,f);while(q--) {int ty,x,y; rd(ty);if(ty==1) {rd(x),rd(y);cut(x);link(x,y);}else if(ty==2) rd(x),printf("%lld\n",getans(x));else printf("%lld %lld\n",*que.begin(),*que.rbegin());}return 0;
}

C - ARC101F Robots and Exits

Sol

对于每个机器人,显然它最终对应的出口只可能是它左边的第一个或者右边的第一个。假设机器人iii对应的两个出口到机器人iii的坐标变化量分别为li,ril_i,r_ili​,ri​,其中li<0,ri>0l_i < 0, r_i > 0li​<0,ri​>0。

考虑机器人们的坐标相对于最初的坐标的变化量关于时间变化的函数,则对于每个机器人来说,它会从哪个口出去,只与这个函数与y=liy=l_iy=li​和y=riy=r_iy=ri​的第一个交点哪一个横坐标更小有关。

观察发现可能的方案数就是将所有的机器人按照lil_ili​从小到大排序(lil_ili​相同则rir_iri​大的放在前面)之后,rir_iri​所能够形成的上升子序列的数量。

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
template <class T>
inline void rd(T &x) {x=0; char c=getchar(); int f=1;while(!isdigit(c)){if(c=='-')f=-1; c=getchar();}while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f;
}
const int N=1e5+10,mod=1e9+7;
struct node {int x,y;node(int x=0,int y=0): x(x),y(y) {}friend bool operator <(node A,node B) { return A.x==B.x?A.y>B.y:A.x>B.x; }friend bool operator ==(node A,node B) { return A.x==B.x&&A.y==B.y; }
}a[N];
int xi[N],yi[N],n,m,cnt;
int val[N],tot;int c[N];
void add(int i,int t) { for(;i<=tot;i+=i&-i) c[i]=(c[i]+t)%mod; }
int query(int i) { int ans=0; for(;i;i-=i&-i) ans=(ans+c[i])%mod; return ans; }
int main() {rd(n),rd(m);for(int i=1;i<=n;++i) rd(yi[i]);for(int i=1;i<=m;++i) rd(xi[i]);for(int i=1;i<=n;++i) {if(yi[i]<=xi[1]||yi[i]>=xi[m]) continue;int r=lower_bound(xi+1,xi+m+1,yi[i])-xi;int l=r-1;a[++cnt]=node(xi[l]-yi[i],xi[r]-yi[i]);}sort(a+1,a+cnt+1);cnt=unique(a+1,a+cnt+1)-a-1;for(int i=1;i<=cnt;++i) val[++tot]=a[i].y;sort(val+1,val+tot+1);tot=unique(val+1,val+tot+1)-val-1;  for(int i=1;i<=cnt;++i) a[i].y=lower_bound(val+1,val+tot+1,a[i].y)-val;int ans=1;for(int i=1;i<=cnt;++i) {int t=(query(a[i].y-1)+1)%mod;ans=(ans+t)%mod;add(a[i].y,t);}printf("%d",ans);return 0;
}

[i].y;
sort(val+1,val+tot+1);
tot=unique(val+1,val+tot+1)-val-1;
for(int i=1;i<=cnt;++i) a[i].y=lower_bound(val+1,val+tot+1,a[i].y)-val;
int ans=1;
for(int i=1;i<=cnt;++i) {
int t=(query(a[i].y-1)+1)%mod;
ans=(ans+t)%mod;
add(a[i].y,t);
}
printf("%d",ans);
return 0;
}

IOI2020集训队作业-9 (CF538G, CF674D, ARC101F)相关推荐

  1. IOI2020集训队作业-23 (CF674F,ARC091F)

    B - CF674F Bears and Juice Sol 最后我们得到的信息是:每头熊有没有睡觉,以及如果睡觉了是在哪一天睡的.我们可能得到的信息的种数显然是桶数量的一个上界.假设总共有 d d ...

  2. (每日一题)P4841 [集训队作业2013]城市规划 (无向连通图计数)(普通生成函数 + 多项式求逆)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.14 生成函数 + 多项式求逆 Pr ...

  3. UOJ#449. 【集训队作业2018】喂鸽子

    #449. [集训队作业2018]喂鸽子 DP好题 法一:min-max容斥 处理前m个,最快吃饱的鸽子期望的时间 根据期望的定义 考虑每个方案数的概率*期望次数 枚举前m个用了x个,概率都是(1/m ...

  4. uoj#422. 【集训队作业2018】小Z的礼物

    uoj#422. [集训队作业2018]小Z的礼物 题目描述 Solution 所有礼物全部取到的方案数并不好求,因此我们考虑min−maxmin-maxmin−max容斥,转化为第一次取到集合中某一 ...

  5. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  6. 2017国家集训队作业[agc016e]Poor Turkey

    2017国家集训队作业[agc016e]Poor Turkey 题意: 一开始有\(N\)只鸡是活着的,有\(M\)个时刻,每个时刻有两个数\(X_i,Y_i\),表示在第\(i\)个时刻在\(X_i ...

  7. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

  8. 【IOI2020国家集训队作业 Part 1】CF505E Mr. Kitayuta vs. Bamboos

    题目 题目描述 Mr. Kitayuta's garden is planted with nn bamboos. (Bamboos are tall, fast-growing tropical p ...

  9. Nuist集训队作业:深度优先搜索(回溯算法)

    Nuist集训队第一次作业:深度优先搜索(回溯算法) 引例 深搜基本思想及回溯算法模板 P1706 全排列问题 P1219 八皇后 P1605 迷宫 P1101 单词方阵 小结 引例 国际西洋棋棋手马 ...

最新文章

  1. java 泛型 .net_Java基础11:Java泛型详解
  2. cordova-config.xml配置应用图标
  3. [vc]如何对radio按钮分组
  4. 28 CO配置-控制-产品成本控制-成本对象控制-期末结算-定义行标识
  5. 虚拟服务器的安全日志,虚拟主机日志分析方法
  6. 视频教程-IT必备技能Cisco认证CCNA全集-思科认证
  7. python科学计算的几个例子
  8. 深度学习识别手写字体数字
  9. 5G通信网络专题报告:新一轮移动通信网络建设迎来高潮
  10. nginx ajax 504,django+uwsgi+nginx ajax post 504 Gateway Time-out
  11. H3C交换机设置时间命令
  12. n维向量,n维向量空间,n维向量空间的维数
  13. django序列化drf2
  14. 紧急:Spring框架被爆出存在0day级别远程命令执行漏洞。漏洞危害程度不亚于log4j漏洞根据目前掌握的信息,JDK版本在9及以上的Spring框架均受影响。该漏洞目前无官方修复补丁
  15. matlab中工作空间的作用,MATLAB的工作空间
  16. 使用 Jenkins 创建微服务应用的持续集成
  17. HTML+CSS鼠标悬停效果
  18. JdbcTemplate报空指针异常 已解决
  19. 简易记账开发笔记之GridLayout
  20. 什么是mes?它的功能有哪些?

热门文章

  1. 如果是你话,跳还是不跳?
  2. 中恒蚁创解读短视频相比于传统的文字媒介有什么优势
  3. 一汽丰田交响音乐会北京收官 亚洲龙和卡罗拉双擎E+亮相
  4. 修改mac地址和ip地址突破内网限制
  5. springboot社区智慧养老监护管理平台设计与实现
  6. gojs动态设置线条颜色及线条上面可写文字。
  7. photoshop如何转PDF以及PDF的预检
  8. 《小狗钱钱》听书笔记
  9. 计算机设备管理系统规划书,设备申请书范文
  10. UG塑胶模具设计的全过程