首页 > 其他 > 详细

停课刷题记录表

时间:2019-09-15 16:43:18      阅读:89      评论:0      收藏:0      [点我收藏+]

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

 

停课刷题记录表

原文:https://www.cnblogs.com/smilke/p/11523009.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!