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

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. Splunk 会议回想: 大数据的关键是机器学习

    作者 Jonathan Allen ,译者 张晓鹏 Splunk的用户大会已经接近尾声.三天时间的会议里,共进行了160多个主题研讨.涵盖了从安全.运营到商业智能.甚至包含物联网,会议中一遍又一遍出现 ...

  2. JavaScript内存示意图

    一.JavaScript内存示意图 二.js原理 1.js执行规则 (1)先定义 定义变量.定义函数.顺序:自上而下. (2)后执行 除了定义外的代码都是执行代码.顺序:自上而下. 2.动态开辟内存 ...

  3. libevent2源码分析之二:初始化流程

    本文并不很详细地分析初始化的各个细节,而重点分析如何将底层操作关联到event_base的相关字段.初始化工作主要是针对event_base的.libevent2支持多种底层实现,有epoll, se ...

  4. linux 安装安装rz/sz 和 ssh

    安装rz,sz yum install lrzsz; 安装ssh yum install openssh-server 查看已安装包 rpm -qa | grep ssh 更新yum源 1.备份 mv ...

  5. SpringMVC+Maven开发项目源码详细介绍

    代码地址如下:http://www.demodashi.com/demo/11638.html Spring MVC概述 Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的W ...

  6. oc block 遍历数组及字典

    原遍历数组NSArray * lines = ...for (NSString * line in lines) { // ...}for (int i = 0; i < lines.count ...

  7. 一道超级坑爹的水题(ACdream oj 无耻的出题人)

     A - 无耻的出题人 Time Limit: 2000/1000 MS (Java/Others)      Memory Limit: 65536/32768 KB (Java/Others) ...

  8. go项目布局(摘录)

    go的项目结构布局 或 包结构布局 这一块大家似乎还在摸索吧, 常用的应该还是类似于java的mvc布局, 但网上也有不同的布局方式,查阅github上的一些源码,也有大量的采用. 我把自己碰到的资料 ...

  9. JanusGraph的schema及数据建模

    每个JanusGraph都有一个schema,该schema由edge labels, property keys和vertex labels组成.JanusGraph的schema可以显式或隐式创建 ...

  10. linux文件系统调用(1)---mount

    术语表: struct mount:挂载点 struct mountpoint:挂载点节点 struct vfsmount:挂载项 源文件系统:用户将要挂载的文件系统 目的文件系统:挂载源文件系统的文 ...