7.16T3奇袭

奇袭

题目描述

由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上 要迎来最终的压力测试——魔界入侵。

唯一一个神一般存在的Administrator被消灭了,靠原本的整合骑士的力量 是远远不够的。所以爱丽丝动员了UW全体人民,与整合骑士一起抗击魔族。

在UW的驻地可以隐约看见魔族军队的大本营。整合骑士们打算在魔族入侵前 发动一次奇袭,袭击魔族大本营!

为了降低风险,爱丽丝找到了你,一名优秀斥候,希望你能在奇袭前对魔族 大本营进行侦查,并计算出袭击的难度。

经过侦查,你绘制出了魔族大本营的地图,然后发现,魔族大本营是一个N ×N的网格图,一共有N支军队驻扎在一些网格中(不会有两只军队驻扎在一起)。

在大本营中,每有一个k×k(1≤k≤N)的子网格图包含恰好k支军队,我们袭 击的难度就会增加1点。

现在请你根据绘制出的地图,告诉爱丽丝这次的袭击行动难度有多大。

输入格式

第一行,一个正整数N,表示网格图的大小以及军队数量。

接下来N行,每行两个整数,Xi,Yi,表示第i支军队的坐标。

保证每一行和每一列都恰有一只军队,即每一个Xi和每一个Yi都是不一样 的。

输出格式

一行,一个整数表示袭击的难度。

样例

样例输入

5
1 1
3 2
2 4
5 5
4 3

样例输出

10

数据范围与提示

样例解释

显然,分别以(2,2)和(4,4)为左上,右下顶点的一个子网格图中有3支军队,这为我们的难度贡献了1点。类似的子网格图在原图中能找出10个。

数据范围

对于30%的数据,N ≤ 100
对于60%的数据,N ≤ 5000
对于100%的数据,N ≤ 50000

这是道毒瘤题,毒瘤的不能再毒瘤,你可以想出各种O(n5),O(n4),O(n3)以至于O(n2)的算法,然而你都会T,且卡常卡不过去,而正解是个O(nlogn)的

关于超时的算法我其实还是想说一说,由于考试的时候我zz,所以最好也就打了一个n4,实际上这题的n3很好打,就是枚举起始点以及块的大小,这个复杂度最多也就T27吧

然后是n2的,那么你就需要认真读题,我没好好读题,我不是人,注意一下我标红加粗那一行(为什么考试的时候没人给我加粗。。。。。),他说每行每列就一个,那我们把这个方格图拍扁怎么样,我们把它从二维搞成一维,也就是表示成a[x]=y的形式,那么思考一下,对于一个区间[L,R],这个LR就是横坐标的范围,也就是子方格图的宽,而a[L]到a[R]之间的max和min就是纵坐标的范围,也就是子方格图的长,那只要max-min=R-L,这个区间就是一个合法的区间,这样的话两层循环枚举L和R就达到了n2,就可以愉快的T67了,据某些Dalao说n2卡一卡可以T91

接下来就是正解了,需要用到刚才拍扁方格的思路,还要用的二分,单调性以及桶

如果我们用二分的想法的话,ans[L,R]=ans[L,mid]+ans[mid+1,R]+跨过mid部分的合法方案,关于前两项,递归下去去算就没问题,重点需要解决的是第三项,我们来想一想这个跨过mid都包含些什么情况

1.min max都在左边

2.min max都在右边

3.min在左边max在右边

4.min在右边max在左边

我们化减一下这四种方案变成  一.最值在同侧  二.最值在异侧

首先我们需要记录一下从mid到L中间这些区间内的最值以及mid+1到R中间这些区间的最值

一.最值在同侧(以均在左侧为例)

如果最值都在左侧,那么就需要满足max[l]-min[l]=r-l,这个和n2的思路是一样的,我们移一下项,就得到了r=max[l]-min[l]+l,那我们就可以枚举这个l,来确定每一个对应的r,来看是不是符合条件

如果都在右侧,同样的思路枚举右端点就可以了

二.最值在异侧(以最小值在左最大值在右为例)

我在说正解之前提到了单调性,那什么具有单调性呢?这个区间max min具有单调性,因为左区间的最值都是有mid开始推的,那从mid到L,min严格不上升,max严格不下降,这个很显然嘛,那同理,从mid+1到Rmin严格不上升,max严格不下降,我们假设左区间是[L,mid],那什么样的右区间是合法的呢?我们设两个指针r1,r2,把他们的初始位置放在mid+1处,我们在移动指针之前先想一想右区间应该满足什么才可以称作合法,诶呀,不就是min[r]>min[l] max[r]>max[l]嘛,关于这个max我们可以找到第一个比max[l]大的,由于这个单调性,第一个max及其之后都大于max[l],我们还可以找到最后一个比min[l]大的,同样由于这个单调性最后一个之后的min都小于min[l],变成了不合法区间,这样的话我们用r1,r2这两个指针找到这个第一个和最后一个,这中间就是合法方案,他还需要满足一个什么条件来着?max[r]-min[l]=r-l,还是移项,那就可以变形为max[r]-r=min[l]-l,这样的话等式两边就变成了两个独立的部分,我们把这个独立的部分扔进桶里,让他进行加加减减的操作我们就可以得到正确的区间数,当然了,我们最开始定下了大左区间[L,mid],我们现在需要缩小它,那r1和r2两个指针也就接着移动就可以了

如果最大值在左,最小值在右,也是一样的思路,在左边找到合法区间,移动右区间就可以了

当然这题还可以翻转,就是那个reverse,代码会变短,复杂度的话多个logn

注意:桶记得清空,min[l]-l可能小于0,所以再加个n

 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxn 50010
 4 #define ll long long
 5 using namespace std;
 6 int n,maxx,minn;
 7 ll ans;
 8 int a[maxn],mi[maxn],ma[maxn],tong[maxn*3];
 9 inline int read()
10 {
11     int e=0,f=1;  char ch=getchar();
12     while(ch<‘0‘||ch>‘9‘)
13     {
14         if(ch==‘-‘)  f=-1;
15         ch=getchar();
16     }
17     while(ch>=‘0‘&&ch<=‘9‘)  {e=(e<<3)+(e<<1)+(ch-48);  ch=getchar();}
18     return e*f;
19 }
20 ll fz(int l,int r)
21 {
22     if(l==r)  return 1;
23     ll da=0,sum=0;  int mid=(l+r)>>1;
24     da=fz(l,mid)+fz(mid+1,r);
25     ma[mid]=mi[mid]=a[mid];
26     for(int i=mid-1;i>=l;--i)  {ma[i]=max(ma[i+1],a[i]);  mi[i]=min(mi[i+1],a[i]);}
27     ma[mid+1]=mi[mid+1]=a[mid+1];
28     for(int i=mid+2;i<=r;++i)  {ma[i]=max(ma[i-1],a[i]);  mi[i]=min(mi[i-1],a[i]);}
29     for(int i=mid;i>=l;--i)//都在左侧
30     {
31         int R=ma[i]-mi[i]+i;
32         if(R<=mid||R>r)  continue;
33         if(ma[R]<ma[i]&&mi[R]>mi[i])  sum++;
34     }
35     for(int i=mid+1;i<=r;++i)//都在右侧
36     {
37         int L=i-ma[i]+mi[i];
38         if(L>=mid+1||L<l)  continue;
39         if(ma[L]<ma[i]&&mi[L]>mi[i])  sum++;
40     }
41     int r1=mid+1,r2=mid+1;//最小值在左,最大值在右
42     while(r1<=r&&mi[r1]>mi[l])  {tong[n+ma[r1]-r1]++;  r1++;}
43     while(r2<=r&&ma[r2]<ma[l])  {tong[n+ma[r2]-r2]--;  r2++;}
44     for(int L=l;L<=mid;++L)
45     {
46         while(r1>mid+1&&mi[r1-1]<mi[L])  {r1--;  tong[n+ma[r1]-r1]--;}
47         while(r2>mid+1&&ma[r2-1]>ma[L])  {r2--;  tong[n+ma[r2]-r2]++;}
48         if(tong[n+mi[L]-L]>0)  sum+=tong[n+mi[L]-L];
49     }
50     for(int i=mid+1;i<=r;++i)  tong[n+ma[i]-i]=0;
51     r1=mid;  r2=mid;//最大值在坐,最小值在右
52     while(r1>=l&&mi[r1]>mi[r])  {tong[n+ma[r1]+r1]++;  r1--;}
53     while(r2>=l&&ma[r2]<ma[r])  {tong[n+ma[r2]+r2]--;  r2--;}
54     for(int R=r;R>=mid+1;--R)
55     {
56         while(r1<mid&&mi[r1+1]<mi[R])  {r1++;  tong[n+ma[r1]+r1]--;}
57         while(r2<mid&&ma[r2+1]>ma[R])  {r2++;  tong[n+ma[r2]+r2]++;}
58         if(tong[n+mi[R]+R]>0)  sum+=tong[n+mi[R]+R];
59     }
60     for(int i=l;i<=mid;++i)  tong[n+ma[i]+i]=0;
61     da+=sum;
62     //cout<<"from"<<l<<"to"<<r<<"sum="<<sum<<endl;
63     return da;
64 }
65 int main()
66 {
67     n=read();
68     for(int i=1;i<=n;++i)  {int o=read(),p=read();  a[o]=p;}
69     ans=fz(1,n);
70     printf("%lld\n",ans);
71     return 0;
72 }

原文地址:https://www.cnblogs.com/hzjuruo/p/11202031.html

时间: 2024-10-19 23:53:49

7.16T3奇袭的相关文章

[JZOJ4687]奇袭

[JZOJ4687]奇袭 题目 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上要迎来最终的压力测试——魔界入侵. 唯一一个神一般存在的Administrator被消灭了,靠原本的整合骑士的力量是远远不够的.所以爱丽丝动员了UW全体人民,与整合骑士一起抗击魔族. 在UW的驻地可以隐约看见魔族军队的大本营.整合骑士们打算在魔族入侵前发动一次奇袭,袭击魔族大本营! 为了降低风险,爱丽丝找到了你,一名优秀斥候,希望你能在奇袭前对魔族大本营进行侦查,并计算出袭击的难度. 

【NOIP2016提高A组8.12】奇袭

题目 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上要迎来最终的压力测试--魔界入侵. 唯一一个神一般存在的Administrator被消灭了,靠原本的整合骑士的力量是远远不够的.所以爱丽丝动员了UW全体人民,与整合骑士一起抗击魔族. 在UW的驻地可以隐约看见魔族军队的大本营.整合骑士们打算在魔族入侵前发动一次奇袭,袭击魔族大本营! 为了降低风险,爱丽丝找到了你,一名优秀斥候,希望你能在奇袭前对魔族大本营进行侦查,并计算出袭击的难度. 经过侦查,你绘制出了魔族大

李愬雪夜袭蔡州:挽救唐朝国祚的关键之战(先示弱于敌军,对降将攻心为上、以诚待人,然后逐步收集情报,最后出奇兵奇袭。但出奇兵也要有预案,否则会被两面夹击。做一件事情真不容易)

元和十年(815年)六月 宰相武元衡遇刺后,唐宪宗任命裴度为宰相,让他继续挑起平定淮西的重担. 裴度对宪宗说:“淮西是朝廷的心腹之疾,不能不除:而且朝廷既已出兵,两河藩镇都在密切关注事态的发展,以决定他们的下一步行动,所以朝廷绝不能半途而废1 七月五日,宪宗下诏历数王承宗的罪行,不许他朝贡,并敦促他幡然悔过,自缚请罪,否则将择日讨伐. 就在朝野上下一致认定王承宗就是刺武案的幕后元凶时,从东都洛阳传来了一个消息,令宪宗和朝臣们大出所料. 消息是东都留守吕元膺送来的.他破获了一起由李师道幕后操纵的未

| 分治-奇袭raid

3.奇袭 (raid.cpp\c\pas) [问题描述] 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上要迎来最终的压力测试——魔界入侵. 唯一一个神一般存在的Administrator被消灭了,靠原本的整合骑士的力量是远远不够的.所以爱丽丝动员了UW全体人民,与整合骑士一起抗击魔族. 在UW的驻地可以隐约看见魔族军队的大本营.整合骑士们打算在魔族入侵前发动一次奇袭,袭击魔族大本营! 为了降低风险,爱丽丝找到了你,一名优秀斥候,希望你能在奇袭前对魔族大本营进行侦

中国野牛气垫艇对登陆战意义 携陆战队奇袭台湾

气垫船可分为全垫升式和部分垫升式,购买自乌克兰的"野牛"气垫登陆艇被认为是当今世界上最大的全升式气垫登陆艇,周围设置了柔性橡胶围裙来约束空气,可使艇体在压缩空气的作用下腾起,与水面脱离接触.部分垫升式气垫船也称为侧壁式气垫船,两侧设置了刚性侧壁,艇首与艇尾为柔性橡胶围裙,以减少空气逃逸,利用升力鼓风机向船底充气,通过螺旋桨或喷水推进前进,这一点与全垫升式气垫船不一样.http://issuu.com/vual49ctcn http://issuu.com/25czdwqwai http

iOS开发的10个奇袭

1.关于关键字volatile 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了.精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份.就像大家更熟悉的const一样,volatile是一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会. Volatile变量具有 synch

bzoj2674 Attack

Description chnlich非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了. 他的敌人有N座城市和N个太守,N个城市可以看作在二维平面上的N个点. N座城市的标号为0,1,2,……,N-1. 第i座城市的坐标为(Xi,Yi),镇守这座城市的太守的能力值为Zi. chnlich每次会选择一个边平行于坐标轴的矩形区域,并奇袭其中太守能力值第K小的城市(奇袭结束之后城市与太守依然存在). 不过,他的敌人经常会偷偷交换两座城市的太守,防止弱点被chnlich

[Math] Weekend 1

1 - 18 题目:D D1分别是线段BC B1C1的中点 过线段AD的中点P作BC的平行线 解析:(1)AB=AC D是BC中点 --> BC垂直AD M N 是中点 MN平行BC MN垂直AD AA1垂直平面ABC MN属于平面ABC --> AA1垂直MN MN 垂直 ADD1A1 (2)设AA1=1 A1作A1E平行于B1C1 以A1位坐标原点 分别以E D1 A作xyz A1(0,0,0) A(0,0,1) 因为P为AD中点 --> M N 为 AB AC中点 M(gh3/2,

一些奇奇怪怪的过题思路

最近考了几次试,做完之后发现自己还是缺乏思维精度和深度--在此把一些奇怪的思路记下来-- 随 题意大概就是拿了一堆数取来取去,这些数在一个模数意义下做乘法,求出操作后取值的期望. 首先,找到这个模数的原根(鬼知道为什么现在出来了),然后就把这些乘法变成加法,然后就是矩阵一通乱搞-- 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using