停课刷题记录表

9月14日:  

luogu P1627 [CQOI2009]中位数 

题意:给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。

一句话题解:根据中位数的性质,将大于b的数记为1,小于b的数记为-1,区间和为0的奇数序列即符合题意,再计数即可。

#include<bits/stdc++.h>

#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define per(i, a, b) for(int i = (a);i >= (b);i--)

using namespace std;

typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
int n, b, a[N], lsum[N], rsum[N]; 
int l[N], r[N], minn = N, maxx = 0;
int pos;
ll ans = 0;
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
    while(ch >='0' && ch <='9'){x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}
    return x*f;
}
int main(){
    n = read(); b = read();
    rep(i, 1, n){ 
        a[i] = read();
        if(a[i] < b) a[i] = -1;
        if(a[i] == b) a[i] = 0, pos = i;
        if(a[i] > b) a[i] = 1;
    }
    rep(i, pos+1, n) rsum[i] = rsum[i-1] + a[i], minn = min(minn, rsum[i]+n);
    per(i, pos-1, 1) lsum[i] = lsum[i+1] + a[i], minn = min(minn, lsum[i]+n);
    l[n] = r[n] = 1;
    rep(i, pos+1, n) r[rsum[i]+n]++;
    per(i, pos-1, 1) l[lsum[i]+n]++;
    maxx = 2*n-minn;
    rep(i, minn, maxx){
        ans += (ll)l[i] * r[2*n-i];
    } 
    printf("%lld\n", ans);
    return 0;
}
View Code

luogu P3407 散步

题意:数轴上有n个人,每秒钟在给定的方向(向东或向西)移动一个距离,当一个人与一个人相遇时两人不再移动,求t秒后,指定m个人所在的位置。

一句话题解:预处理出相遇点,然后二分答案与pos+t进行比较即可。

#include<bits/stdc++.h>

#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define per(i, a, b) for(int i = (a);i >= (b);i--)

using namespace std;

typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
const ll inf = 4557430888798830399;
ll n, t, q;
ll s[N], k = 0;
struct people{ll pos, dic, id; } a[N];
bool mycmp(people a, people b) {return a.pos < b.pos; }
inline ll read(){
    ll x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
    while(ch >='0' && ch <='9'){x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}
    return x*f;
}
int main(){
    n = read(); t = read(); q = read();
    rep(i, 1, n) a[i].pos = read(), a[i].dic = read(), a[i].id = i;
    sort(a+1, a+n+1, mycmp);
    rep(i, 2, n){
        if(a[i].dic == 2 && a[i-1].dic == 1) s[++k] = (a[i].pos+a[i-1].pos)>>1;
    }  
    s[0] = -inf, s[k+1] = inf;
    rep(i, 1, q){
        ll x = read();
        ll posx = a[a[x].id].pos, flag = a[a[x].id].dic;
        ll l = 1, r = k, mid;
        while(l < r){
            mid = (l+r)>>1;
            if(flag == 1){
                if(s[mid] < posx) l = mid+1;
                if(s[mid] > posx) r = mid;
            }
            if(flag == 2){
                if(mid == l) mid++;
                if(s[mid] < posx) l = mid;
                if(s[mid] > posx) r = mid-1;
            }
        }
        mid = l;
        if(s[mid] < posx && flag == 2){
            if(s[mid+1] < posx && s[mid+1] != inf) mid++;
        }
        if(s[mid] > posx && flag == 1){
            if(s[mid-1] > posx && s[mid-1] != inf) mid--; 
        }
        if(flag == 1){
            if(s[mid] > posx+t && s[mid] > posx) printf("%lld\n", posx+t);
            else if(s[mid] < posx) printf("%lld\n", posx+t);
            else if(s[mid] < posx+t && s[mid] > posx) printf("%lld\n", s[mid]);
            else printf("%lld\n", s[mid]);
        }
        if(flag == 2){
            if(s[mid] < posx-t && s[mid] < posx) printf("%lld\n", posx-t);
            else if(s[mid] > posx-t && s[mid] < posx) printf("%lld\n", s[mid]);
            else if(s[mid] > posx) printf("%lld\n", posx-t); 
            else printf("%lld\n", s[mid]);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/smilke/p/11523009.html
今日推荐