区间内所有元素排序后,任意相邻两个元素值差为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 }