【CF】Codeforces Round #539 (Div. 1)

紫名啦!开心owo 开学啦!不开心quq. 以后能写题解都都写div1啦(当然掉下去就orz了) 传送门 A 有一个数列,找出多少个(l,r)使得r−l+1是偶数并且$ a_l * a_{l+1} * a_{l+2} \dots* a_{mid} == a_{mid+1} * a_{mid+2} * \dots * a_r $ 发现可以转化为异或前缀和AR 与AL-1相同。扫一遍边加答案边砸进数组里。


\#include<cstdio> #include<algorithm> #include<cmath> #include<iostream> #include<cstring> #include<queue> #include<stack> #include<vector> using namespace std; typedef long long ll; int n; int JS[1<<20],OS[1<<20]; main() { cin>>n; int now = 0; OS[0]++; ll ans = 0; for(int i=1;i<=n;i++) { int x; cin>>x; now^=x; if(i&1) ans += JS[now],JS[now]++; else ans += OS[now],OS[now]++; } cout<<ans; }
B 给出一个回文串,可以将该回文串切成若干段再任意拼接 使得拼接之后的串也是回文串并且不是原串 求最小的切割次数 先看他能不能一次切完,然后看两次。这个还要根据长度是奇是偶来看,就是一堆特判,很容易一不小心写挂,就是要思路清晰点就好。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>

using namespace std;
char ss[5005];
int n;
char so[5005];
bool hw() {
    bool fk = 1;
    for(int i=1;i<=n;i++) {
        if(so[i]!=ss[i]) {
            fk = 0; break;
        }
    }
    if(fk) return 0;
    int l = n/2,r;
    if(n&1) r = l+2; else r = l+1;
    while(233) {
        if(l==0) return 1;
        if(so[l]!=so[r]) break;
        l--; r++; 
    }
    return 0;
}
bool orz() {
    int st = 0;
    for(int i=2;i<=n;i++) {
        st = 0;
        for(int j=i;j<=n;j++) so[++st] = ss[j];
        for(int j=1;j<i;j++) so[++st] = ss[j];
        if(hw()) return 1;
    }
    return 0;
}
bool wori() {
    bool fk = 1;
    for(int i=1;i<=n;i++) {
        if(i==n/2+1) continue;
        if(ss[i]!=ss[1]) {
            fk = 0; break;
        }
    }
    return fk;
}
int main() {
    scanf("%s",&ss[1]);
    n = strlen(ss+1);
    bool fk = 1;
    for(int i=2;i<=n;i++) {
        if(ss[i]!=ss[i-1]) { 
            fk = 0; break;
        }
    }
    if(fk) {
        puts("Impossible");
        return 0;
    }
    if(n&1) {
        if(orz()) puts("1");
        else if(wori()) puts("Impossible");
        else puts("2");
    } else {
        if(ss[n/2]!=ss[1]) { puts("1"); return 0; }
        if(orz()) puts("1");
        else puts("2");
    } 
}
C 补 q = 1e5次操作 l ,r 1e9 有一个盆,盆内有水,盆内水为0时,结束。有一个水龙头,根据时间变化流量,初始任何时间流量都为0 操作1:修改某个时间点t,使得如果经过该时间点,水流变为v。(保证如果之前这里有1不会再次覆盖) 操作2:删除某个修改1,保证存在。 操作3:模拟时间点l,r之间,给定水盆初始水流。如果l到r之间没有时间点结束,puts("-1"),否则给出时间(eps = 1e-6) 写一棵splay维护序列,初始在两头放(t=0,s=0) , (t=1e9+1,s=0)的两个虚点,每个splay本身维护(t,s)时间和水速度,维护子树(TL,TR,mn,res,spr)表示子树中最小时间和最大时间,从l到r模拟水流时最小的减少量时刻的减少量,从l到r模拟流水之后水的变化量(带符号),最靠后的那个时间的水速度。 之后就靠自己的数据结构功底了orz,考场上直接码出还不FST的大佬orz orz orz
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define int long long
#define zig(x) zigzag(x,1)
#define zag(x) zigzag(x,2)
using namespace std;
typedef double db;
const db eps = 1e-6;
const int maxn = 2e5+5;
int q;
struct mat{
    int tl,tr,spr;
    int re,mn;
};
struct node{
    int ls,rs,fa;
    int sp,tim;
    mat a;
}z[maxn];
int tot,rt;

mat operator+(mat aa,mat bb) {
    mat tmp;
    tmp.tl = aa.tl; tmp.tr = bb.tr;
    tmp.spr = bb.spr;
    tmp.re = aa.re + bb.re + (bb.tl - aa.tr) * aa.spr;
    tmp.mn = min(aa.mn,aa.re + bb.mn + (bb.tl-aa.tr)*aa.spr);
    return tmp;
}
void upd(int x) {
    z[x].a.tl = z[x].a.tr = z[x].tim; z[x].a.spr = z[x].sp;
    z[x].a.re = z[x].a.mn = 0;
    if(z[x].ls) z[x].a = z[z[x].ls].a + z[x].a;
    if(z[x].rs) z[x].a = z[x].a + z[z[x].rs].a;
}
void zigzag(int x,int knd) {
    int y = z[x].fa;
    int o = z[y].fa;
    if(o) {
        if(z[o].ls==y) z[o].ls = x; 
        else z[o].rs = x;
    }
    z[x].fa = o; z[y].fa = x;
    if(knd==1) {
        z[y].ls = z[x].rs;
        z[z[y].ls].fa = y;
        z[x].rs = y;
    } else {
        z[y].rs = z[x].ls;
        z[z[y].rs].fa = y;
        z[x].ls = y;
    }
    upd(y); upd(x);
}
void splay(int x,int zx) {
    int y,o;
    while(z[x].fa!=zx) {
        y = z[x].fa; o = z[y].fa;
        if(o==zx) {
            if(z[y].ls==x) zig(x);
            else zag(x);
        } else {
            if(z[o].ls==y) {
                if(z[y].ls==x) zig(y),zig(x);
                else zag(x),zig(x);
            } else {
                if(z[y].rs==x) zag(y),zag(x);
                else zig(x),zag(x);
            }
        }
    }
    if(!zx) rt = x;
}
void insert(int t,int s) {
    ++tot; z[tot].tim = t; z[tot].sp = z[tot].a.spr = s;
    z[tot].a.tl = z[tot].a.tr = t;
    int p = rt;
    while(233) {
        if(t<z[p].tim) {
            if(z[p].ls) p = z[p].ls;
            else { z[p].ls = tot; break; }
        }
        else {
            if(z[p].rs) p = z[p].rs;
            else { z[p].rs = tot; break; }
        }
    }
    z[tot].fa = p;
    splay(tot,0);
}
int houj(int t) { // >= t
    int p = rt;
    while(233) {
        if(t==z[p].tim) break;
        if(t<z[p].tim) {
            if(z[p].ls&&z[z[p].ls].a.tr>=t) p = z[p].ls;
            else break;
        } else p = z[p].rs;
    }
    return p;
}
int qianq(int t) { // <= t
    int p = rt;
    while(233) {
        if(t==z[p].tim) break;
        if(t>z[p].tim) {
            if(z[p].rs&&z[z[p].rs].a.tl<=t) p = z[p].rs;
            else break;
        } else p = z[p].ls;
    }
    return p;
}
int getr(int p) {
    while(z[p].rs) p = z[p].rs;
    return p;
}
void del(int t) {
    int p = houj(t);
    splay(p,0);
    if(!z[p].ls) { z[z[p].rs].fa = 0; rt = z[p].rs; return; }
    int o = getr(z[p].ls);
    splay(o,p);
    rt = o; z[o].rs = z[p].rs; z[o].fa = 0; z[z[o].rs].fa = o;
    upd(o);
    return;
}
void init() {
    rt = 1;
    ++tot; z[1].rs = 2;
    z[1].sp = 0; z[1].tim = 0; z[1].a.tl = 0; z[1].a.tr = 1e9+1;
    ++tot; z[2].fa = 1;
    z[2].sp = 0; z[2].tim = 1e9+1; z[2].a.tl = z[2].a.tr = 1e9+1;
}
void query(int l,int r,int v) {
    if(v==0) {
        printf("%I64d\n",l);
        return;
    }
    // int pr = qianq(r); int pl = houj(l);
    // if(z[pr].tim<z[pl].tim) {
    //  printf("-1\n");
    //  return;
    // } else if(pr==pl) {
    //  int titi = r - z[pl].tim;
    //  if(1ll*titi*z[pl].sp+v>0) {
    //      puts("-1"); return;
    //  }
    //  db to = v/z[pl].sp;
    //  printf("%.10lf\n",1.0*l+to);
    // }
    // db res = (db)v;
    int pr = houj(r+1); int pl = qianq(l-1);
    splay(pr,0); splay(pl,pr);
    int p = z[pl].rs;
    int res = v;
    if((!p)|| ( res+z[p].a.mn>0 && res + z[p].a.re + z[p].a.spr*(r-z[p].a.tr)>0) ) { puts("-1"); return; }
    while(233) {
        if(z[p].ls&& ( ( (z[z[p].ls].a.mn + res)<=0 ) || ( z[z[p].ls].a.re + res +  z[z[p].ls].a.spr * (z[p].tim-z[z[p].ls].a.tr) <=0) ) ) p = z[p].ls;
        else {
            if(z[p].ls) res += z[z[p].ls].a.re + z[z[p].ls].a.spr * (z[p].tim-z[z[p].ls].a.tr);
            if(z[p].rs&& ( res +  z[p].sp * (z[z[p].rs].a.tl-z[p].tim) > 0 ) ) {
                res +=  z[p].sp * (z[z[p].rs].a.tl-z[p].tim);
                p = z[p].rs;
            } else {
                db to = 1.0*res/(-z[p].sp);
                printf("%.10lf\n",z[p].tim+to);
                break;
            }
        }
    }
    return;
}
main() {
    scanf("%I64d",&q);
    int opt,t,s,l,r,v;
    init();
    for(int i=1;i<=q;i++) {
        scanf("%I64d",&opt);
        if(opt==1) {
            scanf("%I64d%I64d",&t,&s);
            insert(t,s);
        } else if(opt==2) {
            scanf("%I64d",&t);
            del(t);
        } else {
            scanf("%I64d%I64d%I64d",&l,&r,&v);
            //if(q==10000)printf("%I64d %I64d %I64d\n",l,r,v);
            query(l,r,v);
        }
    }
}
D 补 详见
posted @ 2019-02-23 22:01  Newuser233  阅读(7)  评论(0编辑  收藏  举报