1810 连续区间(分治)

Posted happy_code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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!\\n");system("pause");for (;;);exit(0);}
 21         }
 22         return *p1++;
 23     }
 24     inline bool blank(char ch){return ch==\' \'||ch==\'\\n\'||ch==\'\\r\'||ch==\'\\t\';}
 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(\'\\n\');
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(\'\\n\');
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(\'\\n\');}
155         void print(char *s){while (*s)out(*s++);}
156         void println(char *s){while (*s)out(*s++);out(\'\\n\');}
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(\'\\n\');}
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(\'\\n\');}
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++=\'\\n\';}
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++=\'\\n\';}
188     inline void print1(char c){*o++=c;}
189     inline void println1(char c){*o++=c;*o++=\'\\n\';}
190     inline void print1(char *s){while (*s)*o++=*s++;}
191     inline void println1(char *s){print1(s);*o++=\'\\n\';}
192     inline void println1(){*o++=\'\\n\';}
193     inline void flush1(){if (o!=Out){if (*(o-1)==\'\\n\')*--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\\n",x);}
199     inline void print2(char x){printf("%c",x);}
200     inline void println2(char x){printf("%c\\n",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("\\n");}
213     inline void println2(){printf("\\n");}
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&&

以上是关于1810 连续区间(分治)的主要内容,如果未能解决你的问题,请参考以下文章

51Nod 1810 连续区间

利用分治法求n个数的最大连续和

[WC2010]重建计划(分数规划+点分治+单调队列)

P2253 好一个一中腰鼓!

初窥CDQ分治

浅谈CDQ分治