一开始写了个暴力模拟绳子的摆动轨迹

然后在Test 16 T掉了

后来%了一下别人的代码,发现需要对特殊情况进行特殊处理

首先我们考虑绳子的向右摆动,设当前位置为p,绳子当前长度为L

如果其旋转中心位置>p+L/2,那么绳子长度至少会缩短一半

假设一直这样下去,时间复杂度为log(L)

但是当旋转中心位置<p+L/2的时候就比较复杂了,我们发现暴力模拟很容易被卡成单次O(L)

因为这个时候会出现绳子不断地在两个点之间转来转去,每次减少绳长很少

但是我们又会发现挡在两个点之间旋转时候,转一圈减少的长度为2*(p1-p2)

那么不断的在两个点之间旋转我们只需要令L=L%(2*(p1-p2)) 即可

这样就不会被卡成O(L)了

至于对最后答案的判定,我们只需要旋转两次,如果这两次旋转中心相同,证明这就是答案

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std; const int maxn=200010;
int n,m,now,len;
int a[maxn];
int idx[maxn];
int p[maxn]; bool cmp(const int &u,const int &v){return a[u]<a[v];}
int Rotate(int id,int L,int f){
if(f==1)return upper_bound(a+1,a+n+1,a[id]+L)-a-1;
else return lower_bound(a+1,a+n+1,a[id]-L)-a;
}
int Get_ans(int id,int L,int f){
int n1=Rotate(id,L,f);
int n2=Rotate(n1,L-abs(a[n1]-a[id]),f^1);
if(n2==id){
if(id==n1)return id;
int d=2*abs(a[id]-a[n1]);
return Get_ans(id,L%d,f);
}else Get_ans(n1,L-abs(a[n1]-a[id]),f^1);
} int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&a[i]),idx[i]=i;
sort(idx+1,idx+n+1,cmp);sort(a+1,a+n+1);
for(int i=1;i<=n;++i)p[idx[i]]=i;
while(m--){
scanf("%d%d",&now,&len);
printf("%d\n",idx[Get_ans(p[now],len,1)]);
}
return 0;
}

  

codeforces #310 div1 D的更多相关文章

  1. codeforces #310 div1 E

    算得上是比较水的E题了吧,自己想了想写了写居然1A了 对于这道题,我们很容易想到对于原图的一个边双,定向后任意两点间一定可达 那么我们可以求出原图的边双并将每个边双缩成一个点 那么原图就变成了无环的无 ...

  2. codeforces #310 div1 C

    操作无论是U还是L,都会使原图形分裂成两个图形,且两个图形的操作互不影响 我们又发现由于操作点只可能在下斜线上,如果将操作按x排序 那么无论是U还是L,都会将操作序列完整分割成两半,且两个操作序列互不 ...

  3. codeforces #310 div1 B

    我们考虑n-1座桥每座桥需要的长度在一个区间[L,R]中 之后我们现在有m座桥,每个桥的长度为k 题意就是要求一个匹配方案 显然如果数据范围不大直接KM就可以了 可是20w的数据KM显然要T 所以我们 ...

  4. codeforces #310 div1 A

    首先我们考虑最暴力的拆解拼凑 显然拆分掉所有的链需要 n-m 次 之后拼凑需要 n-1 次 然后由题目规定可知:只有从1出发且连续的链不用拆掉,其余的都必须拆掉(因为两个都套有娃娃的套娃不能组合) 我 ...

  5. codeforces 407 div1 B题(Weird journey)

    codeforces 407 div1 B题(Weird journey) 传送门 题意: 给出一张图,n个点m条路径,一条好的路径定义为只有2条路径经过1次,m-2条路径经过2次,图中存在自环.问满 ...

  6. codeforces 407 div1 A题(Functions again)

    codeforces 407 div1 A题(Functions again) Something happened in Uzhlyandia again... There are riots on ...

  7. codeforces #313 div1 E

    首先我们要注意到一个事情 如果一个灯塔向左覆盖,那么比他小的某个灯塔如果向左覆盖的端点大于当前塔向左覆盖的端点,他一定向右覆盖 对于当前灯塔向右覆盖也是同理 那么我们只需要记录当前覆盖到的端点就可以完 ...

  8. codeforces #305 div1 done

    总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目 ...

  9. Codeforces #254 div1 B. DZY Loves FFT 暴力乱搞

    B. DZY Loves FFT 题目连接: http://codeforces.com/contest/444/problem/B Description DZY loves Fast Fourie ...

随机推荐

  1. Bootstrap两端对齐的导航实例

    Bootstrap两端对齐的导航,样式剥离出来代码如下: <!DOCTYPE html> <html> <head> <title>Bootstrap ...

  2. C# DateTimePicker控件详解

    1.同时显示日期和时间 DateTimePicker dtp = new DateTimePicker(); dtp.Format = DateTimePickerFormat.Custom;dtp. ...

  3. java查询WFS服务

    在我们访问wfs服务时候,有时候会遇到前台访问时候的跨域问题.这里给出java访问的一个小例子. import java.io.BufferedReader; import java.io.IOExc ...

  4. WinForm多线程及委托防止界面假死

    当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决. using System; using System.Collections.Generi ...

  5. linux 输入子系统(3)----事件处理(input_handler层)

    输入子系统主要设计input_dev.input_handler.input_handle.如下: [1]每个struct input_dev代表一个输入设备 struct input_dev { c ...

  6. 【原创】一起学C++ 之指针的--/++ ---------C++ primer plus(第6版)

    讲*和++同时用于指针时提出了这样的问题:将什么解除引用,将什么递增. ]={21.1, 32.8, 23.4, 45.2, 37.4 }; double *pt=arr; //pt指针指向arr[0 ...

  7. ZOJ 1074 最大子矩阵和

    Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...

  8. 一、mysql使用入门

    mysql -h localhost -u root -p123456 登录mysql服务器 show databases 列出所拥有的数据库 use www 选择一个www的数据库 show tab ...

  9. SQL 跨服务器数据库增、删、改、查(一)

    --开启本服务器中操作其他服务器的功能 reconfigure --输出消息 reconfigure --输出消息 --增 INSERT INTO OPENROWSET('SQLOLEDB','jx3 ...

  10. C#设计模式学习资料--观察者模式

    http://www.cnblogs.com/promise-7/archive/2012/05/14/2500759.html http://www.cnblogs.com/zhenyulu/art ...