BJ 集训测试8 Problem C 插线板
2018-03-22 16:51
363 查看
http://www.elijahqi.win/archives/2762
题意:1~n号插线板 每个插线板有一个存在的时间每个人有一个使用时间 问插在哪个插线板可以挪动次数最少 每次一个插线板的插入和取走都只会对他后面的一个产生影响
将每个人的操作拆成两个 然后预处理succ表示我操作这个之后会对后面的哪个插线板产生挪动次数的贡献
然后分块 表示这段时间之前到所有点的区间挪动最优值处理出来 针对每个操作使用可持久化块状数组维护 (查询o(1))查询的时候因为我块前面的已经处理出来了 那么显然我只需要考虑我这个块到我这个人需要时间的这些区域里的最小值 我已在sqrt的时间处理出来
题意:1~n号插线板 每个插线板有一个存在的时间每个人有一个使用时间 问插在哪个插线板可以挪动次数最少 每次一个插线板的插入和取走都只会对他后面的一个产生影响
将每个人的操作拆成两个 然后预处理succ表示我操作这个之后会对后面的哪个插线板产生挪动次数的贡献
然后分块 表示这段时间之前到所有点的区间挪动最优值处理出来 针对每个操作使用可持久化块状数组维护 (查询o(1))查询的时候因为我块前面的已经处理出来了 那么显然我只需要考虑我这个块到我这个人需要时间的这些区域里的最小值 我已在sqrt的时间处理出来
#include<set> #include<cstdio> #include<cstring> #include<algorithm> #define N 100010 #define bk 350 #define inf 0x3f3f3f3f using namespace std; inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++; } inline int read(){ int x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();} while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc(); return x*f; } struct Persistent_block_array{ int *p[N/bk+2]; inline void add(int x){ const int bl=x/bk; int *t=new int[bk]; if (p[bl]) memcpy(t,p[bl],sizeof(int)*bk);else memset(t,0,sizeof(int)*bk); ++t[x%bk];p[bl]=t; } inline int query(int x){ const int bl=x/bk;return p[bl]?p[bl][x%bk]:0; } }arr ; struct node{ int id,op,time; }opt ; inline bool cmp(const node &a,const node &b){return a.time<b.time;} set<int> s; int succ ,pre_ans[400] ,sum ,n,m,q,type,L ,R ,last_ans; int main(){ freopen("t3.in","r",stdin); // freopen("t3.out","w",stdout); n=read();m=read();q=read();type=read();int cnt=0; for (int i=1;i<=n;++i){ L[i]=read();R[i]=read();opt[++cnt]=(node){i,1,L[i]};opt[++cnt]=(node){i,0,R[i]}; }sort(opt+1,opt+(n=cnt)+1,cmp); for (int i=1;i<=n;++i){ if (!opt[i].op) s.erase(opt[i].id);set<int>::iterator it; it=s.lower_bound(opt[i].id);if (it!=s.end()) succ[i]=*it; if (opt[i].op) s.insert(opt[i].id); } for (int i=1;i<=n;++i){arr[i]=arr[i-1]; if (!opt[i-1].op&&succ[i-1]) arr[i].add(succ[i-1]); if (opt[i].op&&succ[i]) arr[i].add(succ[i]); } for (int j=1;j<=n;j+=bk){ memset(sum,0,sizeof(sum)); for (int i=j;i<=n;++i) if (succ[i]) ++sum[succ[i]];int mn=inf; for (int i=n;i>=j;--i){int id=opt[i].id,su=succ[i]; if(!opt[i].op&&L[id]<=j) mn=min(mn,sum[id]); if (!opt[i].op&&su){ --sum[su];if (L[su]<=j) mn=min(mn,sum[su]); }pre_ans[j/bk][i]=mn; if (opt[i].op&&su){ --sum[su];if (L[su]<=j) mn=min(mn,sum[su]); } } } for (int i=1;i<=q;++i){ int l=read()^last_ans,r=read()^last_ans;int bl=(l-1)/bk,mn=pre_ans[bl][r]; for (int j=bl*bk+1;j<=l;++j){ const int id=opt[j].id,su=succ[j]; if (R[id]>=r) mn=min(mn,arr[r].query(id)-arr[l].query(id)); if (R[su]>=r) mn=min(mn,arr[r].query(su)-arr[l].query(su)); }last_ans=mn; printf("%d\n",last_ans!=inf?last_ans:-1); last_ans=type==0?0:last_ans;last_ans=last_ans==inf?0:last_ans; 4000 } return 0; }
相关文章推荐
- BJ 集训测试9 Problem C King
- 暑假集训中期测试 Problem G: 维护序列 (线段树)
- BJ 集训测试9 draw
- BJ 集训测试12 coin
- 暑假集训中期测试 Problem H: 跳跳 (最短路)
- BJ 集训测试12 同构
- BJ 集训测试7 Mythological VII
- BJ 集训测试10 序列
- BJ 集训测试11 flow
- BJ 集训测试11 捕鱼
- BJ 集训测试11 level&& codeforces 700E
- BJ 集训8 测试 B 新访问计划
- BJ 集训测试14 pow
- BJ 集训测试14 bird
- BJ 集训测试13 平行
- BJ 集训测试7 A模型
- 暑假集训中期测试 Problem D: 装箱问题2 (并查集)
- BJ 集训测试10 城市
- 暑假集训中期测试 Problem E: 天朝的单行道 (最短路)
- BJ 集训测试6 求和