序列
题目:
给定一个序列,求和最小且为正奇数的区间,如果有多个,则输出字典序最小
【输入格式】
第一行:一个正整数 n。
第二行:n 个整数,第 i 个代表 a i 。
【输出格式】
共一行。
若有解:三个整数,最小权值和,区间左端点,区间右端点。
若无解:一个字符串"-1"(不带引号)。
【样例输入 1】
5
1 -1 3 -2 3
【样例输出 1】
1 1 1
给定一个序列,求权值和为正奇数且最小的区间。
先处理出所有的前缀和,按顺序把它们丢到set 里。
因为要求权值和为正数且最小,那么只需lower_bound 找到在其前面
的第一个元素,用两者差更新答案。
对于奇偶性的要求,那用两个set 分开维护奇数和偶数就好了。
O(n log n)。
不会用STL,直接打的平衡树,没有删除操作,并不难打
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 struct Node 8 { 9 long long key,lev; 10 int p; 11 Node *ch[2]; 12 }treap[600001],*root[2]; 13 Node *pos=treap; 14 long long sum[300001],S,ans=2e15; 15 int n,L=2e9,R=2e9,P; 16 queue<Node*>mem; 17 void NewNode(Node* &r,long long key,int p) 18 { 19 if (mem.empty()) 20 r=pos++; 21 else r=mem.front(),mem.pop(); 22 r->key=key; 23 r->p=p; 24 r->lev=rand(); 25 r->ch[0]=r->ch[1]=0; 26 } 27 void rotate(Node* &r,bool t) 28 { 29 Node* y=r->ch[!t]; 30 r->ch[!t]=y->ch[t]; 31 y->ch[t]=r; 32 r=y; 33 } 34 void insert(Node* &r,long long key,int p) 35 { 36 if (!r) NewNode(r,key,p); 37 else 38 { 39 bool t=r->key<key; 40 insert(r->ch[t],key,p); 41 if (r->ch[t]!=0&&r->ch[t]->lev<r->lev) rotate(r,!t); 42 } 43 } 44 void find(Node* r,long long key) 45 { 46 if (!r) return; 47 if (r->key<key) 48 { 49 if (r->key>S) 50 { 51 S=r->key; 52 P=r->p; 53 } 54 else if (r->key==S) 55 { 56 P=min(P,r->p); 57 } 58 } 59 if (r->key>key&&r->ch[0]) find(r->ch[0],key); 60 else if (r->key<key&&r->ch[1]) find(r->ch[1],key); 61 } 62 int main() 63 {int i; 64 cin>>n; 65 for (i=1;i<=n;i++) 66 { 67 scanf("%lld",&sum[i]); 68 sum[i]+=sum[i-1]; 69 } 70 insert(root[0],0,0); 71 for (i=1;i<=n;i++) 72 { 73 S=-2e15;P=2e9; 74 if (sum[i]%2==1) 75 { 76 find(root[0],sum[i]); 77 if (S!=-2e15&&P!=2e9) 78 { 79 if (sum[i]-S<ans) 80 { 81 L=P;R=i; 82 ans=sum[i]-S; 83 } 84 else if (sum[i]-S==ans) 85 { 86 if (P<L||(P==L&&i<R)) 87 { 88 L=P;R=i; 89 } 90 } 91 } 92 } 93 else 94 { 95 find(root[1],sum[i]); 96 if (S!=-2e15&&P!=2e9) 97 { 98 if (sum[i]-S<ans) 99 { 100 L=P;R=i; 101 ans=sum[i]-S; 102 } 103 else if (sum[i]-S==ans) 104 { 105 if (P<L||(P==L&&i<R)) 106 { 107 L=P;R=i; 108 } 109 } 110 } 111 } 112 insert(root[sum[i]%2],sum[i],i); 113 } 114 if (L==2e9&&R==2e9) 115 cout<<-1; 116 else cout<<ans<<' '<<L+1<<' '<<R; 117 }