1810 连续区间(分治)

基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
区间内所有元素排序后,任意相邻两个元素值差为1的区间称为“连续区间”
如:3,1,2是连续区间,但3,1,4不是连续区间
给出一个1~n的排列,求出有多少个连续区间
Input
一个数n(n<=1,000,000)
第二行n个数,表示一个1~n的排列
Output
一个数,表示有多少个连续区间
Input示例
5
2 1 5 3 4
Output示例
9
样例解释:
区间[1,1][2,2][3,3][4,4][5,5][1,2][4,5][3,4][1,5]为连续区间//[l,r]表示从第l个数到第r个数构成的区间


// 容易想到分治,但是还是没想出怎么细节,唉


写得很详细了,比较好理解,但是,写起来还是要注意挺多地方的,细节很多,写了好久,唉
大部分是超快读入挂
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define MOD 1000000007
  4 #define INF 0x3f3f3f3f
  5 #define eps 1e-9
  6 #define LL long long
  7 #define MX 1000005
  8 
  9 namespace fastIO{
 10     #define BUF_SIZE 100000
 11     #define OUT_SIZE 100000
 12     #define ll long long
 13     //fread->read
 14     bool IOerror=0;
 15     inline char nc(){
 16         static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
 17         if (p1==pend){
 18             p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
 19             if (pend==p1){IOerror=1;return -1;}
 20             //{printf("IO error!
");system("pause");for (;;);exit(0);}
 21         }
 22         return *p1++;
 23     }
 24     inline bool blank(char ch){return ch==' '||ch=='
'||ch=='
'||ch=='	';}
 25     inline void read(int &x){
 26         bool sign=0; char ch=nc(); x=0;
 27         for (;blank(ch);ch=nc());
 28         if (IOerror)return;
 29         if (ch=='-')sign=1,ch=nc();
 30         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 31         if (sign)x=-x;
 32     }
 33     inline void read(ll &x){
 34         bool sign=0; char ch=nc(); x=0;
 35         for (;blank(ch);ch=nc());
 36         if (IOerror)return;
 37         if (ch=='-')sign=1,ch=nc();
 38         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 39         if (sign)x=-x;
 40     }
 41     inline void read(double &x){
 42         bool sign=0; char ch=nc(); x=0;
 43         for (;blank(ch);ch=nc());
 44         if (IOerror)return;
 45         if (ch=='-')sign=1,ch=nc();
 46         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 47         if (ch=='.'){
 48             double tmp=1; ch=nc();
 49             for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
 50         }
 51         if (sign)x=-x;
 52     }
 53     inline void read(char *s){
 54         char ch=nc();
 55         for (;blank(ch);ch=nc());
 56         if (IOerror)return;
 57         for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
 58         *s=0;
 59     }
 60     inline void read(char &c){
 61         for (c=nc();blank(c);c=nc());
 62         if (IOerror){c=-1;return;}
 63     }
 64     //getchar->read
 65     inline void read1(int &x){
 66         char ch;int bo=0;x=0;
 67         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 68         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 69         if (bo)x=-x;
 70     }
 71     inline void read1(ll &x){
 72         char ch;int bo=0;x=0;
 73         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 74         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 75         if (bo)x=-x;
 76     }
 77     inline void read1(double &x){
 78         char ch;int bo=0;x=0;
 79         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 80         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 81         if (ch=='.'){
 82             double tmp=1;
 83             for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
 84         }
 85         if (bo)x=-x;
 86     }
 87     inline void read1(char *s){
 88         char ch=getchar();
 89         for (;blank(ch);ch=getchar());
 90         for (;!blank(ch);ch=getchar())*s++=ch;
 91         *s=0;
 92     }
 93     inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
 94     //scanf->read
 95     inline void read2(int &x){scanf("%d",&x);}
 96     inline void read2(ll &x){
 97         #ifdef _WIN32
 98             scanf("%I64d",&x);
 99         #else
100         #ifdef __linux
101             scanf("%lld",&x);
102         #else
103             puts("error:can't recognize the system!");
104         #endif
105         #endif
106     }
107     inline void read2(double &x){scanf("%lf",&x);}
108     inline void read2(char *s){scanf("%s",s);}
109     inline void read2(char &c){scanf(" %c",&c);}
110     inline void readln2(char *s){gets(s);}
111     //fwrite->write
112     struct Ostream_fwrite{
113         char *buf,*p1,*pend;
114         Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
115         void out(char ch){
116             if (p1==pend){
117                 fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
118             }
119             *p1++=ch;
120         }
121         void print(int x){
122             static char s[15],*s1;s1=s;
123             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
124             while(x)*s1++=x%10+'0',x/=10;
125             while(s1--!=s)out(*s1);
126         }
127         void println(int x){
128             static char s[15],*s1;s1=s;
129             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
130             while(x)*s1++=x%10+'0',x/=10;
131             while(s1--!=s)out(*s1); out('
');
132         }
133         void print(ll x){
134             static char s[25],*s1;s1=s;
135             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
136             while(x)*s1++=x%10+'0',x/=10;
137             while(s1--!=s)out(*s1);
138         }
139         void println(ll x){
140             static char s[25],*s1;s1=s;
141             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
142             while(x)*s1++=x%10+'0',x/=10;
143             while(s1--!=s)out(*s1); out('
');
144         }
145         void print(double x,int y){
146             static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
147                 1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
148                 100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
149             if (x<-1e-12)out('-'),x=-x;x*=mul[y];
150             ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
151             ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
152             if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
153         }
154         void println(double x,int y){print(x,y);out('
');}
155         void print(char *s){while (*s)out(*s++);}
156         void println(char *s){while (*s)out(*s++);out('
');}
157         void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
158         ~Ostream_fwrite(){flush();}
159     }Ostream;
160     inline void print(int x){Ostream.print(x);}
161     inline void println(int x){Ostream.println(x);}
162     inline void print(char x){Ostream.out(x);}
163     inline void println(char x){Ostream.out(x);Ostream.out('
');}
164     inline void print(ll x){Ostream.print(x);}
165     inline void println(ll x){Ostream.println(x);}
166     inline void print(double x,int y){Ostream.print(x,y);}
167     inline void println(double x,int y){Ostream.println(x,y);}
168     inline void print(char *s){Ostream.print(s);}
169     inline void println(char *s){Ostream.println(s);}
170     inline void println(){Ostream.out('
');}
171     inline void flush(){Ostream.flush();}
172     //puts->write
173     char Out[OUT_SIZE],*o=Out;
174     inline void print1(int x){
175         static char buf[15];
176         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
177         while(x)*p1++=x%10+'0',x/=10;
178         while(p1--!=buf)*o++=*p1;
179     }
180     inline void println1(int x){print1(x);*o++='
';}
181     inline void print1(ll x){
182         static char buf[25];
183         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
184         while(x)*p1++=x%10+'0',x/=10;
185         while(p1--!=buf)*o++=*p1;
186     }
187     inline void println1(ll x){print1(x);*o++='
';}
188     inline void print1(char c){*o++=c;}
189     inline void println1(char c){*o++=c;*o++='
';}
190     inline void print1(char *s){while (*s)*o++=*s++;}
191     inline void println1(char *s){print1(s);*o++='
';}
192     inline void println1(){*o++='
';}
193     inline void flush1(){if (o!=Out){if (*(o-1)=='
')*--o=0;puts(Out);}}
194     struct puts_write{
195         ~puts_write(){flush1();}
196     }_puts;
197     inline void print2(int x){printf("%d",x);}
198     inline void println2(int x){printf("%d
",x);}
199     inline void print2(char x){printf("%c",x);}
200     inline void println2(char x){printf("%c
",x);}
201     inline void print2(ll x){
202         #ifdef _WIN32
203             printf("%I64d",x);
204         #else
205         #ifdef __linux
206             printf("%lld",x);
207         #else
208             puts("error:can't recognize the system!");
209         #endif
210         #endif
211     }
212     inline void println2(ll x){print2(x);printf("
");}
213     inline void println2(){printf("
");}
214     #undef ll
215     #undef OUT_SIZE
216     #undef BUF_SIZE
217 };
218 using namespace fastIO;
219 
220 int n;
221 int dat[MX];
222 int tt[MX*2];
223 int ma[MX],mi[MX];
224 LL ans;
225 
226 void func(int l,int r)
227 {
228     int mid = (l+r)/2;
229     ma[mid] = mi[mid] = dat[mid];
230     for (int i=mid-1;i>=l;i--)
231     {
232         ma[i] = max(ma[i+1],dat[i]);
233         mi[i] = min(mi[i+1],dat[i]);
234     }
235     ma[mid+1] = mi[mid+1] = dat[mid+1];
236     for (int i=mid+2;i<=r;i++)
237     {
238         ma[i] = max(ma[i-1],dat[i]);
239         mi[i] = min(mi[i-1],dat[i]);
240     }
241     for (int i=l;i<=mid;i++)    // 都在左边
242     {
243         int j = ma[i] - mi[i] + i;
244         if (j>mid&&j<=r&&ma[j]<ma[i]&&mi[j]>mi[i]) ans++;
245     }
246     for (int j=mid+1;j<=r;j++)  // 都在右边
247     {
248         int i = -(ma[j] - mi[j]) + j;
249         if (i>=l&&i<=mid&&ma[i]<ma[j]&&mi[i]>mi[j]) ans++;
250     }
251     //左大 右小
252     int l_=mid+1, r_=mid;
253     for (int i=mid;i>=l;i--)
254     {
255         while (r_<r&&ma[r_+1]<ma[i])
256         {
257             r_++;
258             tt[mi[r_]+r_]++;
259         }
260         while(l_<=r_&&mi[l_]>mi[i])
261         {
262             tt[mi[l_]+l_]--;
263             l_++;
264         }
265         ans += tt[ma[i] + i];
266     }
267     while(l_<=r_) {tt[mi[l_]+l_]--;l_++;}
268     //左小,右大
269     l_ = mid+1, r_=mid;
270     for (int j=mid+1;j<=r;j++)
271     {
272         while (l_>l&&ma[l_-1]<ma[j])
273         {
274             l_--;
275             tt[mi[l_]-l_+MX]++;
276         }
277         while(r_>=l_&&mi[r_]>mi[j])
278         {
279             tt[mi[r_]-r_+MX]--;
280             r_--;
281         }
282         ans += tt[ma[j]-j+MX];
283     }
284     while(r_>=l_) {tt[mi[r_]-r_+MX]--; r_--;}
285 
286     if (l==r) return ;
287     func(l,mid); func(mid+1,r);
288 }
289 
290 int main()
291 {
292     fastIO::read(n);
293     for (int i=1;i<=n;i++)
294         fastIO::read(dat[i]);
295     func(1,n);
296     printf("%lld
",ans+n);
297     return 0;
298 }
View Code





原文地址:https://www.cnblogs.com/haoabcd2010/p/7635092.html