제출 #1347245

#제출 시각아이디문제언어결과실행 시간메모리
1347245ender_shayanZIGZAG (INOI20_zigzag)C++20
100 / 100
632 ms67984 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double	ld;
typedef pair<int, int>	pii  ;
typedef pair<ll, ll>	pll  ;
typedef vector<pii>     vii  ;
typedef vector<int>     veci ;
typedef vector<pll>     vll  ;
typedef vector<ll>      vecll;

// find_by_order             order_of_key

//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define F		        first
#define S		        second
#define pb		        push_back
#define endl            '\n'
#define Mp		        make_pair
#define all(x)          x.begin(), x.end()
#define debug(x)        cerr << #x << " = " << x << endl
#define set_dec(x)	    cout << fixed << setprecision(x);
#define fast_io         ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_io         freopen("in.txt" , "r" , stdin) ; freopen("out.txt" , "w" , stdout);
#define lb              lower_bound
#define ub              upper_bound
#define for1(n)         for(int i=1;i<=n;i++)
#define for0(n)         for(int i=0;i<n;i++)
#define forn(n)         for(int i=n;i>0;i--)
#define pq              priority_queue <pii, vector<pii>, greater<pii>>


const int N=3e5+10;
int A[N],n,m,k,q;

ll lz[N*4];bool lzz[N*4];
struct Node{
    int oo;//
    int o1=2;//
    int o2=2;//
    ll ans;//
    int t1;//
    int t2;//
    ll val1;//
    ll val2;//
}seg[N*4],cl;
Node merg(Node a,Node b){
    if(a.t1==0)return b;
    if(b.t1==0)return a;
    Node c;c.ans=a.ans+b.ans;c.oo=0;
    c.val1=a.val1;c.val2=b.val2;
    c.t1=a.t1;
    c.t2=b.t2;
    if(((a.o2==1 || a.o2>1) && (b.o1==1 || b.o1>1) && a.val2>b.val1) || ((a.o2==0 || a.o2>1) && (b.o1==0 || b.o1>1) && a.val2<b.val1)){
        c.ans+=1ll*a.t2*b.t1;
        if(a.oo)
            c.t1+=b.t1;
        if(b.oo)
            c.t2+=a.t2;
        if(a.oo && b.oo)
            c.oo=1;
    }
    else if(((a.o2==1 || a.o2>1) && a.val2>b.val1) || ((a.o2==0 || a.o2>1) && a.val2<b.val1)){
        c.ans+=a.t2;
        if(a.oo)
            c.t1++;
    }
    else if(((b.o1==1 || b.o1>1) && a.val2>b.val1) || ((b.o1==0 || b.o1>1) && a.val2<b.val1)){
        c.ans+=b.t1;
        if(b.oo)
            c.t2++;
    }
    else
        c.ans+=(a.val2!=b.val1);


    if(a.o1>1)a.o1=(a.val2==b.val1 ? -1:(a.val2<b.val1));
    c.o1=a.o1;
    if(b.o2>1)b.o2=(a.val2==b.val1 ? -1:(a.val2<b.val1));
    c.o2=b.o2;
    return c;
}
void shift(int l,int r,int v){
    if(r-l==1)return;
    if(lzz[v]!=0){
        lzz[v<<1]^=1;
        lz[v<<1]*=-1;
        if(seg[v<<1].o1!=-1)seg[v<<1].o1^=1;
        if(seg[v<<1].o2!=-1)seg[v<<1].o2^=1;
        seg[v<<1].val1*=-1;
        seg[v<<1].val2*=-1;


        lzz[v<<1|1]^=1;
        lz[v<<1|1]*=-1;
        if(seg[v<<1|1].o1!=-1)seg[v<<1|1].o1^=1;
        if(seg[v<<1|1].o2!=-1)seg[v<<1|1].o2^=1;
        seg[v<<1|1].val1*=-1;
        seg[v<<1|1].val2*=-1;

        lzz[v]=0;
    }
    if(lz[v]!=0){
        lz[v<<1]+=lz[v];
        seg[v<<1].val1+=lz[v];
        seg[v<<1].val2+=lz[v];

        lz[v<<1|1]+=lz[v];
        seg[v<<1|1].val1+=lz[v];
        seg[v<<1|1].val2+=lz[v];

        lz[v]=0;
    }
}
void build(int l=1,int r=n+1,int v=1){
    if(r-l==1){
        seg[v].ans=seg[v].t1=seg[v].t2=seg[v].oo=1;
        seg[v].val1=seg[v].val2=A[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,v<<1);
    build(mid,r,v<<1|1);
    seg[v]=merg(seg[v<<1],seg[v<<1|1]);
//    cout<<l<<" "<<r<<":"<<seg[v].oo<<" "<<seg[v].o1<<" "<<seg[v].o2<<endl;
//    cout<<seg[v].t1<<" "<<seg[v].t2<<" "<<seg[v].val1<<" "<<seg[v].val2<<endl;
//    cout<<seg[v].ans<<endl;
}
void updd(int lx,int rx,int l=1,int r=n+1,int v=1){
    shift(l,r,v);
    if(lx>=r || rx<=l)return;
    if(lx<=l && r<=rx){
        seg[v].val1*=-1;
        seg[v].val2*=-1;
        seg[v].o1^=1;
        seg[v].o2^=1;
        lz[v]*=-1;
        lzz[v]^=1;
        return;
    }
    int mid=(l+r)>>1;
    updd(lx,rx,l,mid,v<<1);
    updd(lx,rx,mid,r,v<<1|1);
    seg[v]=merg(seg[v<<1],seg[v<<1|1]);
}
void upd(int lx,int rx,int x,int l=1,int r=n+1,int v=1){
    shift(l,r,v);
    if(lx>=r || rx<=l)return;
    if(lx<=l && r<=rx){
        seg[v].val1+=x;
        seg[v].val2+=x;
        lz[v]+=x;
        return;
    }
    int mid=(l+r)>>1;
    upd(lx,rx,x,l,mid,v<<1);
    upd(lx,rx,x,mid,r,v<<1|1);
    seg[v]=merg(seg[v<<1],seg[v<<1|1]);
}
Node get(int lx,int rx,int l=1,int r=n+1,int v=1){
    shift(l,r,v);
    if(lx>=r || rx<=l)return cl;
    if(lx<=l && r<=rx)return seg[v];
    int mid=(l+r)>>1;
    return merg(get(lx,rx,l,mid,v<<1),get(lx,rx,mid,r,v<<1|1));
}
int main(){
    fast_io
    int T;
    cin>>n>>T;
    for1(n)cin>>A[i];
    build();
    while(T--){
        char a;int l,r;cin>>a>>l>>r;r++;
        int x;
        if(a=='?'){
            cout<<get(l,r).ans<<endl;
//            int ans=0;
//            for(int i=l;i<r;i++){
//                int p=(A[i]<A[i+1]),o=1;ans+=min(2,r-i);
//                for(int j=i+2;j<r;j++){
//                    if(A[j-1]>A[j])o&=p;
//                    else o&=(p==0);
//                    ans+=o;
//                    p=(A[j-1]<A[j]);
//                }
//            }
//            cout<<ans<<endl;
        }
        else if(a=='*')updd(l,r);
        else{
            cin>>x;
            upd(l,r,x);
        }
    }




}
/*
6 8
-2 7 3 4 1 6
? 1 6
+ 3 5 4
* 1 6
+ 5 6 -3
? 2 5
* 3 5
+ 4 4 -2
? 3 6

6 8
-2 7 7 8 8 9
? 1 6
+ 3 5 4
* 1 6
+ 5 6 -3
? 2 5
* 3 5
+ 4 4 -2
? 3 6



*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...