hehezhou 的鬼才神仙题解根本看不懂好吧。

首先判掉 \(n=1\)。

然后考虑最后一步,发现只用考虑怎样的左右端点可能见面。

左右和右左构成双射,算出总量减去自己配自己再除 \(2\) 即可。

于是考虑怎样的端点可以被生成。

容易发现结论:

\([l_1,r_1)[l_2,r_2)\dots[l_m,r_m)\) 可以合成 \([\min l,\max r)\) 内所有点。(左闭右开方便后面操作)

把所有 \(l,r\) 拉出来排序,考虑每一段区间内的点能够达到的

对于一个点,其左右必须各选至少一个点,从而将其“框住”。

考虑一个显然的事实:

如果对一个点,其左边端点数达到 \(4\) 且右边端点达到 \(4\)(或者,更准确的,除了最左最右端点及其对应端点外还分别有端点),则其可以和 \([\min l,\max r)\) 中所有端点配对!

这部分贡献直接 \(O(1)\) 统计,

剩下的部分,区间数量是 \(O(1)\) 的,且其中一半的端点数目是 \(O(1)\) 的,考虑暴力枚举具体使用的一对区间端点,

然后可以对最左、最右可行端点暴力移动枚举,显然移动也是 \(O(1)\) 的,

最后再取这些可行区间的并即可。

怎么取并呢?

对每次得到的可行端点对,更新左端点对应的最大右端点,

然后对其用单调性扫描一遍,再差分即可。

可能有点不大清楚,但估计代码还是看得懂的。

下面是核心代码。

std::pair<uint,uint>P[200005];
int main()
{
#ifdef MYEE
freopen("QAQ.in","r",stdin);
// freopen("QAQ.out","w",stdout);
#endif
uint t;scanf("%u",&t);
while(t--){
uint n;scanf("%u",&n);
for(uint i=0;i<n;i++)
scanf("%u%u",&P[i<<1].first,&P[i<<1|1].first),
P[i<<1].first--,P[i<<1].second=P[i<<1|1].second=i;
if(n==1){puts("1");continue;}
std::sort(P,P+(n<<1));
ullt ans=0;
for(uint i=1;i<n*2;i++)if(P[i].first!=P[i-1].first){
ullt wil=0;
if(i>=4&&n*2-i>=4)
wil=P[n*2-1].first-P[0].first-1;
else{
static uint R[200005];
for(uint j=0;j<n*2;j++)R[j]=j;
for(uint x=0;x<i;x++)for(uint y=i;y<n*2;y++){
uint l=0,r=n*2-1;
while(l<n*2&&(P[l].second==P[x].second||P[l].second==P[y].second))
l++;
if(l==n*2)continue;
while(~r&&(P[r].second==P[x].second||P[r].second==P[y].second))
r--;
_max(R[l],r);
}
for(uint j=1;j<n*2;j++)_max(R[j],R[j-1]);
for(uint j=0;j+1<n*2;j++)if(R[j]>j)
wil+=i==j+1?P[i].first-P[j].first-1:P[j+1].first-P[j].first;
}
ans+=wil*(P[i].first-P[i-1].first);
}
ans/=2;
printf("%llu\n",ans);
}
return 0;
}

gym104076H的更多相关文章

随机推荐

  1. springboot配置ssl变成https证书

    前段时间跳槽了,疫情期间啥也干,回想了这个项目当中的一些新接触的东西记下来,为了方便以后自己看,也给新手提供以下便利.如果这边篇随笔能够给你带来便利,小衲不胜荣幸,如果有错误也欢迎批评指正,大家共同学 ...

  2. calendar.getActualMaximum(calendar.DAY_OF_MONTH)的陷阱,2月份最后一天成了3月3号

    引用一下别人的链接: https://blog.csdn.net/dongyuxu342719/article/details/78131697

  3. C++ 手动实现队列(queue) (课后作业版)

    #include <iostream> using namespace std; template <typename T> class Queue { public: Que ...

  4. (jmeter笔记)jmeter用正则匹配响应数据,满足两个条件

    方法1.用正则匹配响应数据,满足两个条件 \{[^}]+?"Id":(\d*)[^}]+?"Picking"[^}]+?\} 方法2. \{"Pick ...

  5. Tiup离线安装TIDB集群4.0.16版本

    环境:centos7.6 中控机:8.213.8.25(内网) 可用服务器8.213.8.25-8.213.8.29 一.准备 TiUP 离线组件包 方法1:外网下载离线安装包拷贝进内网服务器 在Ti ...

  6. python_类 对象 属性

    1, 类 (class) 类的概念表示某种对象的集合,用于表示某一种相同对象的模板.例如:人作为一个类 由这个"人"类定义出来的内容就是这个类定义出来的对象,类还拥有属性和功能,属 ...

  7. js判断数组的方法

    1.实例的__proto__ 属性 非标准ie浏览器不支持 let arr = [1,2,3]; console.log('__proto__',arr.__proto__ === Array.pro ...

  8. Spring Boot--自定义异常类

    1.业务异常 /** * @Description: 业务异常 * @Author: Yaoson * @Create: 2022/4/21 0:05 **/ public class Busines ...

  9. C 数值类型与字节数组相互转化

    C 数据类型与字节数组相互转化 uint16_t -> bytes uint8_t uint16_t2bytes(uint8_t* buffer, uint16_t data) { if(buf ...

  10. 错误 C2664 “int fputs(const char *,FILE *)”: 无法将参数 1 从“char”转换为“const char *”解决方法

    遇到这个问题,请打开本项目的Properties(属性) -------> Configuration Properties(配置属性) -------->General(常规) ---- ...