NC26128. Segment Tree
描述
输入描述
第一行输入一个正整数,代表询问个数
接下来q行,每行输入1~2个正整数,含义见题目描述。
题目保证
输出描述
对于每个询问输出一行,五个整数,依次代表被更新的区间起始下标、终止下标、数组的和、数组的最小值及数组的最大值。
示例1
输入:
5 1 3 2 2 1 2 1 5
输出:
0 2 3 1 1 3 4 7 1 2 0 2 4 2 2 3 4 0 0 0 0 4 5 1 1
说明:
第一次询问后,数组变成[1, 1, 1, 0, 0, ...],更新了a[0]~a[2]的区间,,最小值和最大值都为1。C++11(clang++ 3.9) 解法, 执行用时: 2020ms, 内存消耗: 4192K, 提交时间: 2019-06-08 17:01:34
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int>pii; set<pii>dat; map<int,pii>MP; void solve(){ //MP[0]=pii(0,99999999); dat.insert(pii(0,9999999)); ll sum=0; int Q; scanf("%d",&Q); while(Q--){ int x; scanf("%d",&x); if(MP.count(x)){ pii t=MP[x]; printf("%d %d ",t.first,t.second); sum-=1LL*x*(t.second-t.first+1); MP.erase(x); printf("%lld ",sum); if(MP.size()) printf("%d %d\n",MP.begin()->first,(--MP.end())->first); else printf("0 0\n"); auto it=dat.lower_bound(t); if(it!=dat.begin()){ --it; if(it->second+1==t.first){ t.first=it->first; dat.erase(it); } } it=dat.lower_bound(t); if(it->first-1==t.second){ t.second=it->second; dat.erase(it); } dat.insert(t); } else{ int n; scanf("%d",&n); sum+=1LL*x*n; for(auto P:dat){ if(P.second-P.first+1>=n){ pii t=pii(P.first,P.first+n-1); MP[x]=t; printf("%d %d ",t.first,t.second); printf("%lld ",sum); printf("%d %d\n",MP.begin()->first,(--MP.end())->first); dat.erase(P); if(P.second-P.first+1>n){ dat.insert(pii(P.first+n,P.second)); } break; } } } } } int main(){ solve(); return 0; }
C++14(g++5.4) 解法, 执行用时: 2100ms, 内存消耗: 4068K, 提交时间: 2019-06-08 15:26:32
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int>pii; set<pii>dat; map<int,pii>MP; void solve(){ //MP[0]=pii(0,99999999); dat.insert(pii(0,9999999)); ll sum=0; int Q; scanf("%d",&Q); while(Q--){ int x; scanf("%d",&x); if(MP.count(x)){ pii t=MP[x]; printf("%d %d ",t.first,t.second); sum-=1LL*x*(t.second-t.first+1); MP.erase(x); printf("%lld ",sum); if(MP.size()) printf("%d %d\n",MP.begin()->first,(--MP.end())->first); else printf("0 0\n"); auto it=dat.lower_bound(t); if(it!=dat.begin()){ --it; if(it->second+1==t.first){ t.first=it->first; dat.erase(it); } } it=dat.lower_bound(t); if(it->first-1==t.second){ t.second=it->second; dat.erase(it); } dat.insert(t); } else{ int n; scanf("%d",&n); sum+=1LL*x*n; for(auto P:dat){ if(P.second-P.first+1>=n){ pii t=pii(P.first,P.first+n-1); MP[x]=t; printf("%d %d ",t.first,t.second); printf("%lld ",sum); printf("%d %d\n",MP.begin()->first,(--MP.end())->first); dat.erase(P); if(P.second-P.first+1>n){ dat.insert(pii(P.first+n,P.second)); } break; } } } } } int main(){ solve(); return 0; }