matrix_last_acm_2
2014年广州站网络赛 北大命题 password 123
B http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97257#problem/B
题意:长度为n的墙,一开始1-n都是2号颜色,m次操作,P是将a到b都涂成c号,Q是查询a到b之间内有哪些颜色,从小到大输出。
解法:颜色只有30种,可以用30位二进制表示某种颜色有或者没有,1表示有,0表示没有,线段树根节点就是两个儿子的二进制或。
//#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e5+;
struct OP{
char str[];
int a,b,c;
}op[M];
int n,m;
#define lrrt int L,int R,int rt
#define iall 1,n,1
#define imid int mid=(L+R)>>1
#define lson L,mid,rt<<1
#define rson mid+1,R,rt<<1|1
struct T{
int state,lazy;
}tree[(M*)<<];
void pushup(int rt){
tree[rt].state=tree[rt<<].state|tree[rt<<|].state;
}
void pushdown(int rt){
if(tree[rt].lazy){
tree[rt<<].lazy=tree[rt].lazy;
tree[rt<<|].lazy=tree[rt].lazy;
tree[rt<<].state=tree[rt].lazy;
tree[rt<<|].state=tree[rt].lazy;
tree[rt].lazy=;
}
}
void build(lrrt){
tree[rt].lazy=;
if(L==R){
tree[rt].state=;
return ;
}
imid;
build(lson);
build(rson);
pushup(rt);
}
void update(int x,int y,int z,lrrt){
if(x<=L&&R<=y){
tree[rt].state=z;
tree[rt].lazy=z;
return ;
}
imid;
pushdown(rt);
if(mid>=x) update(x,y,z,lson);
if(mid<y) update(x,y,z,rson);
pushup(rt);
}
int query(int x,int y,lrrt){
if(x<=L&&R<=y) return tree[rt].state;
imid;
pushdown(rt);
int ans=;
if(mid>=x) ans|=query(x,y,lson);
if(mid<y) ans|=query(x,y,rson);
return ans;
}
void solve(){
build(iall);
for(int i=;i<m;i++){
if(op[i].str[]=='P'){
update(op[i].a,op[i].b,<<(op[i].c-),iall);
continue;
}
op[i].c=query(op[i].a,op[i].b,iall);
}
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(~scanf("%d%d",&n,&m),n|m){
for(int i=;i<m;i++){
scanf("%s%d%d",op[i].str,&op[i].a,&op[i].b);
if(op[i].str[]=='Q') continue;
scanf("%d",&op[i].c);
}
solve();
for(int i=;i<m;i++){
if(op[i].str[]=='P') continue;
bool out=false;
for(int j=;j<;j++){
if((op[i].c>>j)&){
if(out) putchar(' ');
printf("%d",j+);
out=true;
}
}
puts("");
}
}
return ;
}
C http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97257#problem/C
题意:n*n的矩阵,.可以走,#不能走。8个方向走,上下左右,还有45度的四个方向。最多只能转弯一次且一定要转90度,问最长的路径的长度。
解法:先预处理出每个点8个方向最远能走的长度。然后枚举每个起点,枚举8个方向,每走一步都尝试左转90和右转90,取最大值。
//#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
int dp[M][M][];
int n;
int dx[]={-,-,,,,,,-};
int dy[]={,,,,,-,-,-};
bool inside(int x,int y){
return x>=&&x<n&&y>=&&y<n;
}
void init_dp(){
for(int i=;i<n;i++){
for(int j=;j<n;j++){
for(int k=;k<;k++){
dp[i][j][k]=;
int tx=i;
int ty=j;
while(inside(tx,ty)&&a[tx][ty]=='.'){
dp[i][j][k]++;
tx+=dx[k];
ty+=dy[k];
}
}
}
}
}
int solve(){
init_dp();
int res=;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(a[i][j]=='#') continue;
for(int k=;k<;k++){
int step=;
int tx=i;
int ty=j;
while(inside(tx,ty)&&a[tx][ty]=='.'){
res=max(res,step+dp[tx][ty][(k+)%]);
res=max(res,step+dp[tx][ty][(k-+)%]);
tx+=dx[k];
ty+=dy[k];
step++;
}
}
}
}
return res;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(~scanf("%d",&n),n){
for(int i=;i<n;i++){
scanf("%s",a[i]);
}
printf("%d\n",solve());
}
return ;
}
D http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97257#problem/D
题意:n*n的矩形,K起点,T终点,上下左右走,每一步一秒,到达终点前要集齐m个钥匙,钥匙编号要从小到大收集,第一次遇到的S要多花一秒,问最少几秒完成。
解法: bfs,状态 x y 拥有钥匙的最大号 key,蛇的状态 state,如果用队列,遇到s时杀了,要停在原地。另一种方法是直接进s,step+=2,需要优先队列。
//#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
int n,m;
struct Q{
int x,y,key,state;
}now,pre;
queue<Q> q;
int dist[M][M][][<<];
int length_of_snake;
int snake[M][M];
int dx[]={,,,-};
int dy[]={,-,,};
void init_snake(){
length_of_snake=;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(a[i][j]!='S') continue;
snake[i][j]=length_of_snake++;
}
}
}
void init(){
init_snake();
int big=<<length_of_snake;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
for(int k=;k<=m;k++){
for(int s=;s<big;s++){
dist[i][j][k][s]=inf;
}
}
}
}
while(!q.empty()) q.pop();
}
void want_to_push(int x,int y,int key,int state,int step){
if(dist[x][y][key][state]>step){
dist[x][y][key][state]=step;
now.x=x;
now.y=y;
now.key=key;
now.state=state;
q.push(now);
}
}
void get_start(){
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(a[i][j]!='K') continue;
want_to_push(i,j,,,);
return ;
}
}
}
bool inside(int x,int y){
return x>=&&x<n&&y>=&&y<n;
}
int solve(){
init();
get_start();
while(!q.empty()){
pre=q.front();
q.pop();
for(int i=;i<;i++){
int tx=pre.x+dx[i];
int ty=pre.y+dy[i];
if(!inside(tx,ty)) continue;
if(a[tx][ty]=='#') continue;
int pre_step=dist[pre.x][pre.y][pre.key][pre.state];
if(a[tx][ty]=='T'){
if(pre.key==m) return pre_step+;
want_to_push(tx,ty,pre.key,pre.state,pre_step+);
continue;
}
if(a[tx][ty]=='S'){
if((pre.state>>snake[tx][ty])&){
want_to_push(tx,ty,pre.key,pre.state,pre_step+);
continue;
}
want_to_push(pre.x,pre.y,pre.key,pre.state|(<<snake[tx][ty]),pre_step+);
continue;
}
if(isdigit(a[tx][ty])){
if(pre.key+==a[tx][ty]-''){
want_to_push(tx,ty,pre.key+,pre.state,pre_step+);
continue;
}
}
want_to_push(tx,ty,pre.key,pre.state,pre_step+);
}
}
return -;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(~scanf("%d%d",&n,&m),n|m){
for(int i=;i<n;i++){
scanf("%s",a[i]);
}
int ans=solve();
if(ans==-){
puts("impossible");
continue;
}
printf("%d\n",ans);
}
return ;
}
H http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97257#problem/H
题意:给一颗树,n个节点。给m次操作,每次操作x到y路径上的每一个点都增加一个种类编号是z的物品,最后问每一个节点 个数最多的种类编号,如果有多个个数相同的种类,输出编号最小的。如果没有物品输出0.
解法:1.树链剖分转化为一维线段的同样的问题。2.对区间x到y增加一个z,可以用一个数组vector存,x位置存z,y+1位置存-z。把所有的操作都存好后,遍历线段上的点,将该点上vector存的都加入线段树中,最后在线段树查最大个数的下标。线段树1-z,每一个位置代表种类为i 的个数。
//#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e5+;
int n,m;
struct E {
int u,v;
} e[M];
struct C {
int x,y,z;
} c[M];
vector<int> lazy[M];
int answer[M];
int to_id[M];
int big_z;
class Shu_Lian_Pou_Fen { ///树链剖分
static const int MV=1e5+; ///点的个数
struct G {
struct E {
int v,next;
} e[MV<<];
int le,head[MV];
void init(int n) {
le=;
for(int i=; i<=n; i++) head[i]=-;
}
void add(int u,int v) {
e[le].v=v;
e[le].next=head[u];
head[u]=le++;
}
} g;
public:
int n,Index,fa[MV],num[MV],son[MV],dep[MV],sid[MV],top[MV];
void dfs(int u) {
num[u]=;
son[u]=;
for(int i=g.head[u]; ~i; i=g.e[i].next) {
int v=g.e[i].v;
if(v!=fa[u]) {
fa[v]=u;
dep[v]=dep[u]+;
dfs(v);
if(num[son[u]]<num[v]) son[u]=v;
num[u]+=num[v];
}
}
}
void get(int u,int Top) {
sid[u]=++Index;
top[u]=Top;
if(son[u]) get(son[u],Top);
for(int i=g.head[u]; ~i; i=g.e[i].next) {
int v=g.e[i].v;
if(v!=fa[u]&&v!=son[u]) {
get(v,v);
}
}
}
public:
void init(int tn) { ///传入点数下标1 开始
n=tn;
g.init(n);
}
void add(int u,int v) {
g.add(u,v);
g.add(v,u);
}
void solve() {
fa[]=dep[]=num[]=Index=;
dfs();
get(,);
}
void update(int x,int y,int z) {
lazy[x].push_back(z);
lazy[y+].push_back(-z);
}
void work(int x,int y,bool edge_index,int z) { ///边编号(用深度大的点一一对应)传入true,点编号传false
int tx=top[x],ty=top[y];
while(tx!=ty) {
if(dep[tx]<dep[ty]) {
swap(tx,ty);
swap(x,y);
}
update(sid[tx],sid[x],z);
x=fa[tx];
tx=top[x];
}
if(edge_index) {
if(x==y) return ;
if(dep[x]>dep[y]) swap(x,y);
update(sid[son[x]],sid[y],z);
return ;
}
if(dep[x]>dep[y]) swap(x,y);
update(sid[x],sid[y],z);
}
}gx;
void init_lazy() {
gx.init(n);
for(int i=;i<n-;i++){
gx.add(e[i].u,e[i].v);
}
gx.solve();
for(int i=;i<=n;i++){
lazy[i].clear();
}
for(int i=;i<m;i++){
gx.work(c[i].x,c[i].y,false,c[i].z);
}
}
#define lrrt int L,int R,int rt
#define iall 1,big_z,1
#define imid int mid=(L+R)>>1
#define lson L,mid,rt<<1
#define rson mid+1,R,rt<<1|1
struct T{
int value,sum;
}tree[M<<];
void pushup(int rt){
if(tree[rt<<].sum>=tree[rt<<|].sum){
tree[rt].value=tree[rt<<].value;
tree[rt].sum=tree[rt<<].sum;
}
else{
tree[rt].value=tree[rt<<|].value;
tree[rt].sum=tree[rt<<|].sum;
}
if(tree[rt].sum==){
tree[rt].value=;
}
}
void build(lrrt){
if(L==R){
tree[rt].value=L;
tree[rt].sum=;
return ;
}
imid;
build(lson);
build(rson);
pushup(rt);
}
void update(int x,int y,lrrt){
if(L==R){
tree[rt].sum+=y;
return ;
}
imid;
if(mid>=x) update(x,y,lson);
else update(x,y,rson);
pushup(rt);
}
int get_big_z(){
int res=;
for(int i=;i<m;i++){
if(c[res].z<c[i].z){
res=i;
}
}
return c[res].z;
}
void solve() {
if(m==){
for(int i=;i<=n;i++){
answer[i]=;
}
return ;
}
init_lazy();
big_z=get_big_z();
build(iall);
for(int i=;i<=n;i++){
to_id[gx.sid[i]]=i;
}
for(int i=;i<=n;i++){
int len=lazy[i].size();
for(int j=;j<len;j++){
int value=lazy[i][j];
int add=;
if(value<){
value=-value;
add=-;
}
update(value,add,iall);
}
answer[to_id[i]]=tree[].value;
}
}
int main() {
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(~scanf("%d%d",&n,&m),n|m) {
for(int i=; i<n-; i++) {
scanf("%d%d",&e[i].u,&e[i].v);
}
for(int i=; i<m; i++) {
scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].z);
}
solve();
for(int i=; i<=n; i++) {
printf("%d\n",answer[i]);
}
}
return ;
}
end
matrix_last_acm_2的更多相关文章
随机推荐
- pm2 开机自启动如何弄?
1.使用pm2启动node :# pm2 start /home/wwwroot/web.js --watch 2.dump这些进程列表:# pm2 save 3.生成自启动脚本:# pm2 star ...
- centos查看设置端口开放状态
centos查看端口是否已开放/etc/init.d/iptables status centos开放端口/sbin/iptables -I INPUT -p tcp --dport 8000 -j ...
- php下intval()和(int)转换有哪些区别
想知道使用intval()和(int)转换有什么区别? 或者说两者有什么不同,包括功能.定义方面的.或者和使用频率.效率等. 复制代码代码如下: <?php echo "<br ...
- SQL Server中查询结果拼接遇到的小问题
前天的项目,刚接手,对于模块还不是很熟悉,其中有一个模块,涉及到4个表,其中主要的表就有两个,只要把这个弄清楚了就一切回归于“太平”了. 模块要求:把两个表的内容查询出来,结果连接在一起.大师说完,感 ...
- 【代码】ini 文件读取工具类
using System; using System.Runtime.InteropServices; using System.Text; namespace hrattendance.Common ...
- 关于iphone消息推送把C#当服务器端来发送
看了苹果消息推送文档,感觉推送很简单的,但是还是按个人习惯把这些简单知识记录下来,在需要时候再查看一下! 在开发之前,要准备以下的资料 1.证书(包括产生证书和调试证书) 2.证书密码 3.唯一标识( ...
- Jquery + echarts 使用
常规用法,就不细说了,按照官网一步步来. 本文主要解决问题(已参考网上其他文章): 1.把echarts给扩展到JQuery上,做到更方便调用. 2.多图共存 3.常见的X轴格式化,钻取时传业务实体I ...
- Hive与HBase区别
对于刚接触大数据的用户来说,要想区分Hive与HBase是有一定难度的.本文将尝试从其各自的定义.特点.限制.应用场景等角度来进行分析,以作抛砖引玉之用. ====Hive是什么?Apache Hiv ...
- easyui 布局自适应
最近在把以前写的一个项目改成用easyui做前端.过程中遇到了不少问题.其中一个就是datagrid不能很好的布局.想了好多办法都有局限.最后想到会不会是布局(easyui-layout)的问题,经过 ...
- FPGA中如何实现除法?
摘自:<xilinx FPGA 开发实用教程> 1)被除数重复的减去除数,直到检测到余数小于除数为止,优点:对于除数与被除数相差较小的情况下合适 2)通过如下图片方式实现+状态机.优点:挺 ...