想了最复杂的思路,用了最纠结的方法,花了最长的时间,蒙了一种规律然后莫名其妙的过了。

MD 我也太淼了。

后面想了下用状压好像还是挺好写的,而且复杂度也不高。推出的这个容斥的规律也没完全想透我就CAO。

Count the Grid

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 400    Accepted Submission(s): 86

Problem Description
You get a grid of h rows and w columns. Rows are numbered 1, 2, 3, ... , h from top to bottom while columns are numbered 1, 2 , 3, ... , w from left to right. Each cell can be represented by a pair of numbers (x, y), which means this cell is located at row x column y.
You fill the every cell with an integer ranging from 1 to m.
Then you start to play with the gird. Every time you chose a rectangle whose upper left cell is (x1, y1) and lower right cell is (x2, y2), finally you calculate the maximum value v of this rectangle.
After you played n times, you left. When you return, you find that the grid is disappeared. You only remember n rectangles and their corresponding maximum value. You are wondering how many different gird can satisfy your memory. Two grids are different if there is a cell filled different integer.
Give your answer modulo (109+7).
Your memory may have some mistakes so that no grid satisfies it, in this case just output 0.
 
Input
Multiple test cases. In the first line there is an integer T, indicating the number of test cases. For each test case. First line contain 4 integers h, w, m, n. Next are n lines, each line contain 5 integers x1, y1, x2, y2, v.
(T=55,1≤h,w,m≤104,1≤x1≤x2≤h,1≤y1≤y2≤w,1≤v≤m,1≤n≤10, there are i test cases for n = i)
 
Output
For each test case, please output one line. The output format is "Case #x: ans", x is the case number, starting from 1.
 
Sample Input
2
3 3 2 2
1 1 2 2 2
2 2 3 3 1
4 4 4 4
1 1 2 3 3
2 3 4 4 2
2 1 4 3 2
1 2 3 4 4
 
Sample Output
Case #1: 28
Case #2: 76475
 
Source
 
Recommend
hujie   |   We have carefully selected several similar problems for you:  5493 5492 5491 5490 5489 
 
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
#define MOD 1000000007 int h,w,m,n;
struct node
{
int x1,y1,x2,y2;
int num;
int areacnt;
int area[];//记录其中的小区域
}g[],tg[]; struct Rect
{
int x1,y1,x2,y2;
}rect[]; bool flag_noans;
int tmpsaverect[];
int tmprectcnt; long long savemul[];
bool saverectinarea[][];
bool flagrect[];
bool flagarea[];
bool flagg[];
int x[],y[];
long long ans;
long long tmpans;
long long ansans; bool cmpgnum(node tl,node tr)
{
return tl.num<tr.num;
} bool checkareabelong(int rectpoint,int gi)
{
if(g[gi].x1<=rect[rectpoint].x1&&g[gi].y1<=rect[rectpoint].y1 && g[gi].x2>=rect[rectpoint].x2&&g[gi].y2>=rect[rectpoint].y2 )
{
return ;
}
return ;
} int getrectareanum(int i)
{
return (rect[i].y2-rect[i].y1+)*(rect[i].x2-rect[i].x1+);
} long long quick_pow(int aa,int bb)//a^b
{
long long ans_pow=;
long long tmp_pow=aa;
while(bb)
{
if(bb&)
ans_pow = (ans_pow*tmp_pow)%MOD;
tmp_pow = (tmp_pow*tmp_pow)%MOD;
bb>>=;
}
return ans_pow;
} long long cnt_bigoneism(int allnum,int bigm)
{
return ((quick_pow(bigm,allnum)-quick_pow(bigm-,allnum))%MOD+MOD)%MOD;
} void dfs(int s,int ends,int cnt_nowhave,int tmp_m)
{
//明显错了
if(cnt_nowhave!=)
{
int cnt_inarea=;
int cnt_outarea=;
for(int i=;i<tmprectcnt;i++)
{
int tmp_flag=;
for(int j=;j<ends;j++)
{
if(flagarea[j]==true)
{
if( saverectinarea[i][j]==true )
{
tmp_flag=;
cnt_inarea += getrectareanum( tmpsaverect[i] );
break;
} /*
if( tg[j].x1<=rect[tmpsaverect[i]].x1&&tg[j].y1<=rect[tmpsaverect[i]].y1&& tg[j].x2>=rect[tmpsaverect[i]].x2&&tg[j].y2>=rect[tmpsaverect[i]].y2 )
{
tmp_flag=1;
cnt_inarea += getrectareanum( tmpsaverect[i] );
break;
}
*/
}
}
if(tmp_flag==)
{
cnt_outarea += getrectareanum( tmpsaverect[i] );
} }
if( !(cnt_outarea==||cnt_inarea==) )
{
long long tmp_sum = ( quick_pow(tmp_m-,cnt_inarea)*cnt_bigoneism(cnt_outarea,tmp_m) )%MOD;
ansans = (ansans+savemul[cnt_nowhave]*tmp_sum)%MOD;
}
}
for(int i=s;i<ends;i++)
{
flagarea[i]=true;
dfs(i+,ends,cnt_nowhave+,tmp_m);
flagarea[i]=false;
}
} long long get_numtime(int mxt,int tm)
{
//有t个不满足的情况
memset(flagarea,false,sizeof(flagarea));
ansans=;
dfs(,mxt,,tm);
return ansans;
} int main()
{
int T;
int tt=;
scanf("%d",&T);
//设计模式还是很成问题。
while(T--)
{
flag_noans=false;
scanf("%d%d%d%d",&h,&w,&m,&n);
for(int i=;i<n;i++)
{
int x1,y1,x2,y2,tmp;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&tmp);
x[*i]=x1;
x[*i+]=x2+;
y[*i]=y1;
y[*i+]=y2+; g[i].x1=x1;g[i].y1=y1;
g[i].x2=x2;g[i].y2=y2;
g[i].num=tmp;
g[i].areacnt=;
}
x[*n]=;
x[*n+]=h+;
y[*n]=;
y[*n+]=w+;
int id=;//用来标记最小矩形
sort(x,x+*(n+));
sort(y,y+*(n+));
int prex=;
for(int i=;i<*(n+);i++)
{
if(x[i]==prex) continue;
int prey=;
for(int j=;j<*(n+);j++)
{
if(y[j]==prey) continue;
rect[id].x1=prex;
rect[id].y1=prey;
rect[id].x2=x[i]-;
rect[id].y2=y[j]-;
prey=y[j];
id++;
}
prex=x[i];
} for(int i=;i<id;i++)
{
for(int j=;j<n;j++)
{
if( checkareabelong(i,j) == true )
{
g[j].area[ g[j].areacnt ]=i;
g[j].areacnt++;
}
}
} //然后就是容斥原理了 int cntother=;//统计有多少个格子是完全没有拘束的
for(int i=;i<id;i++)
{
bool signareain=;
for(int j=;j<n;j++)
{
if( checkareabelong(i,j)==true )
{
signareain=true;
break;
}
}
if(signareain == false)
{
cntother += getrectareanum(i);
}
}
ans=quick_pow(m,cntother);
sort(g,g+n,cmpgnum);
memset(flagrect,false,sizeof(flagrect));
for(int i=;i<n;i++)
{
int ti;
for(ti=i;ti<n;ti++)
{
if( g[ti].num != g[i].num ) break;
tg[ti-i]=g[ti];
}
int cntcnt=;//用来判断不满足条件的情况
memset(flagg,,sizeof(flagg));
ti--;
//[i,ti] have the same .num
tmprectcnt=;
int tmpcntnum=;
for(int j=;j<id;j++)
{
if( flagrect[j]==true ) continue;//已经计数过的,不需要
for(int gi=i;gi<=ti;gi++)
if( checkareabelong(j,gi)==true )
{
flagrect[j]=true;
tmpsaverect[tmprectcnt]=j;
tmpcntnum += getrectareanum(j);
tmprectcnt++;
break;
}
for(int gi=i;gi<=ti;gi++)
{
if( checkareabelong(j,gi)==true )
{
if(flagg[gi]==)
{
flagg[gi]=;
cntcnt++;
}
}
}
} //容斥原理开始
if(tmprectcnt==||cntcnt!=ti-i+)
{
flag_noans=true;
break;
} for(int j=;j<tmprectcnt;j++)
for(int j1=;j1<ti-i+;j1++)
{
if( tg[j1].x1<=rect[tmpsaverect[j]].x1&&tg[j1].y1<=rect[tmpsaverect[j]].y1&& tg[j1].x2>=rect[tmpsaverect[j]].x2&&tg[j1].y2>=rect[tmpsaverect[j]].y2 )
{
saverectinarea[j][j1]=true;
}
else saverectinarea[j][j1]=false;
} tmpans = cnt_bigoneism(tmpcntnum,g[i].num);// 总的个数
int flag_sign = -;
long long num_mul=;
for(int j=;j<=ti-i;j++)
{
savemul[j]=flag_sign*num_mul;
//tmpans = tmpans + flag_sign*num_mul*get_numtime(j,ti-i+1,g[i].num);//j个不满足的情况
//tmpans = (tmpans%MOD+MOD)%MOD;
flag_sign *= -;
//num_mul=(num_mul*(j+1))%MOD; }
get_numtime(ti-i+,g[i].num);
tmpans = tmpans + ansans;
ans = (ans*tmpans)%MOD;
i=ti;//这一步一直忘了
}
printf("Case #%d: ",tt++);
if(flag_noans==true)
cout<<<<endl;
else cout<<(ans%MOD+MOD)%MOD<<endl;
}
return ;
}

hdu 5471(状压DP or 容斥)的更多相关文章

  1. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  2. 【HDOJ5519】Kykneion asma(状压DP,容斥)

    题意:给定n和a[i](i=0..4),求所有n位5进制数中没有前导0且i出现的次数不超过a[i]的数的个数 2<=n<=15000,0<=a[i]<=3e4 思路:设f(n, ...

  3. bzoj4036 [HAOI2015]按位或 状压DP + MinMax 容斥

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4036 题解 变成 \(2^n-1\) 的意思显然就是每一个数位都出现了. 那么通过 MinMa ...

  4. 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)

    传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi​表示保证集合iii中所有点都连通其余点随意的方案数. gig ...

  5. HDU 4778 状压DP

    一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...

  6. HDU 3001 状压DP

    有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路  成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到 ...

  7. hdu 2809(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809 思路:简单的状压dp,看代码会更明白. #include<iostream> #in ...

  8. hdu 2167(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2167 思路:经典的状压dp题,前后,上下,对角8个位置不能取,状态压缩枚举即可所有情况,递推关系是为d ...

  9. Engineer Assignment HDU - 6006 状压dp

    http://acm.split.hdu.edu.cn/showproblem.php?pid=6006 比赛的时候写了一个暴力,存暴力,过了,还46ms 那个暴力的思路是,预处理can[i][j]表 ...

随机推荐

  1. 虚拟机oracle virtualbox 上安装centos6.5 网络设置

    上篇文章写到,在虚拟机上安装centos6.5,结果依照文章非常顺利的安装了,可是用yum安装软件的时候.报错,源有问题,不能下载,然后ping一下摆渡.非常悲催 dns解析不了,cat /etc/r ...

  2. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-TwinCAT自带的找原点功能块MC_Home怎么用

    对于相对编码器类型轴(包括虚拟轴),可以使用贝福提供的找原点功能块MC_Home.   HomingMode是指机器在往前跑的时候(30单位/s的默认速度),当碰到阻挡,则会有一个布尔值从FALSE改 ...

  3. 怎样实现广度优先遍历(BFS)

    BFS过程: 一:訪问顶点V,并标记V为已经訪问 二:顶点V入队列 三:假设队列非空.进行运行,否则算法结束 四:出队列取得对头顶点u,假设顶点未被訪问,就訪问该顶点,并标记该顶点为已经訪问 五:查找 ...

  4. sqlite3 sqlite3_prepare、sqlite3_step使用

    void select_by_prepare (sqlite3* pDB){ 51     int i; 52     int ret = 0; 53     int time; 54     cha ...

  5. 自定义通用dialogFragment

    代码地址如下:http://www.demodashi.com/demo/12844.html 前言 之前写过一篇dialogFragmnet封装默认dialog的文章 DialogFragment创 ...

  6. oracle linux 6 docker 安装

    docker对安装系统的内核版本有严格的要求,本文针对oracle linux 6.5进行讲解,其它系统参见: https://docs.docker.com/v1.5/installation/ 下 ...

  7. 深入PHP中慎用双等于(==)的详解

    PHP比较运算符出现的频率实在是太高了,尤其是 ==if(a == b){// do something}但是,你真的掌握了 == 了吗?细节很重要!来看下面的代码,说出你认为正确的答案var_dum ...

  8. SDRAM驱动篇之简易SDRAM控制器的verilog代码实现

    在Kevin写的上一篇博文<SDRAM理论篇之基础知识及操作时序>中,已经把SDRAM工作的基本原理和SDRAM初始化.读.写及自动刷新操作的时序讲清楚了,在这一片博文中,Kevin来根据 ...

  9. DM36x IPNC OSD显示中文 --- 实战篇

    通过数据准备篇,将数据准备好后,其实剩下的工作已经很简单了,通过以下几个步骤即可把一个中文显示在OSD画面上:1. 使用SWOSD_setBmpchangeWinXYPrm函数设置好OSD显示坐标位置 ...

  10. spring 第一篇(1-2):管理你的beans

    在基于spring的应用中,你的应用对象存活在spring container(容器中).容器创建,将它们装配到一起.还有配置和管理它们完整的生命周期(从生到死) 下一章节,你会看到如何配置Sprin ...