题目:
注意有绝对值。
那么就是 k*p 对 q 取模,找最接近 \(\frac{q}{2}\) 的结果。
也就是 2*k*p 对 2*q 取模,找最接近 q 的结果。
一个二元组,第一维表示 %2q 后与 q 的距离,第二维表示自己的 编号。
对 n 个二元组排序太花时间。
令 \( g(x) = 2*p*x mod (2*q) \)
把 n 分块,只排序第一个块里的元素。因为 \( g(x+y) = g(x) + g(y) ( mod (2*q) ) \) ,所以其他块里的大小关系也可以通过第一个块的情况得知。
具体来说,设块大小是 bs ,在第 i 块就是要找与 \( q - 2*p*i*bs \) 最接近的元素。
用 lower_bound 的话,为了方便可以使 a[ tot+1 ] = a[ 1 ] , a[ 0 ] = a[ tot ] 。但是不能 a[ 0 ].first = a[ 1 ].first - 2*p , a[ 0 ].second = a[ 1 ].second - 1 ,因为模 2*q 意义下访问 0 就是要访问 tot 而不是真的 0 位置。
一定要注意相同 fir 只能保留最小的 second ,并且别用 unique 因为该函数不能做到刚才那个要求!!!
#include#include #include #include #define mkp make_pair#define fi first#define se second#define ll long longusing namespace std;const int N=4e4+5,INF=1e9+5;int a,b,p,q,p2,q2,bs,tot;pair c[N],ans;int main(){ int T;scanf("%d",&T); while(T--) { scanf("%d%d%d%d",&a,&b,&p,&q); p2=2*p; q2=2*q; bs=sqrt(b-a+1); tot=0; for(int i=0;i