论静态查错的重要性。。。乱搞题真难调

首先这题看起来就是要分治检验了。

考虑对于区间[l,r],分成[l,p-1]和[p,r]使得这两个区间合并可以得到[l,r],并且要保证后面一个区间较大

设前一个区间长度为pL,合法只有i∈[p,r],i和(i-p)%pL有一条边,并且(i-p)%pL是i第一个连向的区间里面的点,并且i连向的第二个点不能<p

维护一个排过序的邻接表,last数组表示在当前区间内第x个点指向的第1个点,对于前两个条件,我们可以理解为找一个长度pL,假设<=l+pL-1的点都指向自己,那么整个区间的指向构成一个l~l+pL-1的循环

而对于当前区间分割,l一定是归于左边的

把所有和l右边的代入验证是一个基本的思路,但其实我们试两次就够了

考虑对于区间[l,(r-l+1)/2]指向l的最后一个点p,如果要分割,它一定是要归到右区间的

此时我们先找出它进行一次验证,当验证到某个点失配的时候跳出,假设这个点为u

不难发现,只有匹配长度没有超过pL,才有可能有另外的方案,否则循环节的长度已经被确定了,此时我们知道:[p,u-1]和[l,l+u-1-p]是匹配的,而到达u开始失配,那么u只能指向l构成循环节,才有合法的可能

那么通过p和u就确定了循环节长度,我们只需要验证l+u-p即可

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath> using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int check(int p,int l,int r)
{
int pL=p-l,flag=;
for(int x=p,q=;x<=r;x++,q++,q%=pL)
{
int k=last[x];
if(k==||a[k].y!=l+q)
{
if(a[k].y==l)return x;
else return -;
}
else if(a[k].next!=&&a[a[k].next].y<p)flag=-;
}
return flag;
}
bool divi(int l,int r)
{
if(l==r)return true;
for(int x=l;x<=r;x++)
while(last[x]!=&&a[last[x]].y<l)last[x]=a[last[x]].next;
if(l+==r)
if(last[r]!=&&a[last[r]].y==l&&a[last[r]].next==)return true; int p=-,L=r-l+;
for(int x=r-;x>l;x--)
if(last[x]!=&&a[last[x]].y==l&&(x-l)*<=L){p=x;break;}
int x=p;
if(x==-)return false; int z=check(x,l,r);
if(z==)
{
if(divi(l,p-)&&divi(p,r))return true;
}
else if(z!=-)
{
if(z-x>x-l)return false;
int u=l+(z-x);
if(check(u,l,r)==&&divi(l,u-)&&divi(u,r))return true;
}
return false;
} struct edge{int x,y;}e[];
bool cmp(edge e1,edge e2){return e1.x>e2.x;}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int n,m; bool bk=true;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&e[i].x,&e[i].y);
if(e[i].x>e[i].y)swap(e[i].x,e[i].y);
if(e[i].x==e[i].y)bk=false;
}
if(bk==false){printf("NO\n");continue;} sort(e+,e+m+,cmp);
len=;memset(last,,sizeof(last));
for(int i=;i<=m;i++)ins(e[i].y,e[i].x);
if(divi(,n-))printf("YES\n");
else printf("NO\n");
} return ;
}

bzoj4594: [Shoi2015]零件组装机的更多相关文章

  1. 【LOJ】#2040. 「SHOI2015」零件组装机

    题解 我写的应该有bug但是我懒得改了 就是最后一次合并的n要么是0点边集的最后一条边,要么是0点边集最后两条边的差,我们分别拎出来判断一下哪个可行(也许两个都可行,但是我不想多做修改了--) 然后递 ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. 洛谷 P4269 / loj 2041 [SHOI2015] 聚变反应炉 题解【贪心】【DP】

    树上游戏..二合一? 题目描述 曾经发明了零件组装机的发明家 SHTSC 又公开了他的新发明:聚变反应炉--一种可以产生大量清洁能量的神秘装置. 众所周知,利用核聚变产生的能量有两个难点:一是控制核聚 ...

  4. SHOI做题记录

    LOJ #2027. 「SHOI2016」黑暗前的幻想乡 考虑到每个公司一条边,那就等价于没有任何一家公司没有边. 然后就可以容斥+矩阵树定理,没了. LOJ #2028. 「SHOI2016」随机序 ...

  5. luogu[2093]零件分组

    题目描述 某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(Wi).现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长度和重量都不下降(若i<j,则Li<=Lj ...

  6. 零件分组_DP

    问题 C: 零件分组 时间限制: 1 Sec  内存限制: 64 MB提交: 31  解决: 14[提交][状态][讨论版] 题目描述 某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(W ...

  7. Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合

    4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 178  Solved: 70[Submit][Stat ...

  8. 基于Intranet的零件库管理信息系统设计--part01

    好吧,临近毕业的我,毕业设计还没开始做呢.时间不等人,再过两个月就要答辩了,我得开始做我的毕设了,虽然我现在还没能力完全把毕设做出来,但总得先迈出第一步吧.今天先做一小部分. 话不多说,先来看我得毕业 ...

  9. bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]

    4591: [Shoi2015]超能粒子炮·改 题意:多组询问,求 \[ S(n, k) = \sum_{i=0}^n \binom{n}{i} \mod 2333,\ k \le n \le 10^ ...

随机推荐

  1. H5在ios弹窗状态下调起输入法后关闭输入法页面元素错位解决办法

    最近开发移动端,有个需求:点击退款弹出文本框和发送短信按钮,输入手机号码和验证码确定退款. 发现安卓手机没毛病,但是在ios手机上点击文本框调起输入法,此时点击完成或者关闭输入法就无法正常操作了,肉眼 ...

  2. c#如何判断textbox中输入的数据是datatime型的

    ()你好,标准的方法是用一个验证控件:RangeValidator,把type设为DateTime,最大值设为'3000-1-1'或者别的,最小值最好设为'1900-1-1'. ()程序里面自己验证: ...

  3. react.js 渲染一个列表的实例

    //引入模块 import React,{Component} from 'react'; import ReactDOM from 'react-dom'; //定义一个要渲染的数组 let use ...

  4. BZOJ2196: [Usaco2011 Mar]Brownie Slicing

    n<=500 * m<=500的方阵,先沿横坐标切A-1刀,再把每一块切B-1刀,得到A*B块,求这A*B块的数字之和的最小值的最大值. 最小值最大--二分,然后贪心切.每次扫一行,看这一 ...

  5. RedisDesktopManager 踩坑之旅

    虚拟机上装了redis, 本地Windows的RedisDesktopManager  connect failed. 解决方法: 1.修改 redis.conf 文件 bind 127.0.0.1 ...

  6. python学习之-- mysql模块和sqlalchemy模块

    简单介绍python下操作mysql数据库模块有2个:pyhton-mysqldb  和 pymysql 说明:在python3中支持mysql 的模块已经使用pymysql替代了MysqlDB(这个 ...

  7. response对象学习

    import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpSer ...

  8. MongoDB学习day08--Mongoose索引、Mongoose内置方法、扩展Mongoose Model的静态方法和实例方法

    一.Mongoose索引 索引是对数据库表中一列或多列的值进行排序的一种结构, 可以让我们查询数据库变得更快. MongoDB 的索引几乎与传统的关系型数据库一模一样, 这其中也包括一些基本的查询优化 ...

  9. C# 错误!!容量超出了最大容量。参数名: capacity 这个是什么问题呢?

    C# 错误!!容量超出了最大容量.参数名: capacity 这个是什么问题呢?   对于这个问题我纠结了好久老是报错误,报这个错误的原因是应为我加了皮肤的控件,在没有加皮肤控件的时候没有这个错误, ...

  10. sys.argv的妙用:python命令行参数列表的修改、增加、删除

    是否妙用取决于你怎么用 1.sys.argv是用来获取命令行参数的方法,本身是一个list.你搜其实用方法,这方面的介绍最多,这里不赘述 2.那么问题是:sys.argv可以赋值吗?可以扩充吗?可以修 ...