包含不小于$\sqrt n$列的只有不大于$\sqrt n$行,修改时这些行打标记,否则暴力更新,操作一列的时候暴力更新这些行。合并没啥影响直接搞就是了。更新需要访问位置,感觉必须用哈希表,并不是特别靠谱。平均复杂度$O(n\sqrt n)$。

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
int n2;
inline void upd2(int&a,int b){
a<b?a=b:0;
}
struct vec{
int s,d;
gp_hash_table<int,int>w;
vec(){s=d=0;}
void ins(int i,int e){
auto j=w.find(i);
if(w.end()==j)w[i]=e-d;
else
upd2(j->second,e-d);
upd2(s,e);
}
};
gp_hash_table<int,vec>f[2];
gp_hash_table<int,int>g[2];
gp_hash_table<int,null_type>h[2];
void dev(int k,int x){
auto&a=f[k][x];
for(int y:h[k^1]){
auto&b=f[k^1][y];
auto i=b.w.find(x);
if(b.w.end()!=i)
a.ins(y,i->second+b.d);
}
}
int sol5(int k,int x){
if(h[k].end()==h[k].find(x))
dev(k,x);
return f[k][x].s;
}
int ask(int k,int x){
return g[k].end()!=g[k].find(x)?sol5(k,g[k][x]):0;
}
void inc(int k,int x,int d){
auto&a=f[k][x];
if(h[k].end()==h[k].find(x)){
dev(k,x);
for(auto&e:a.w){
e.second+=d;
f[k^1][e.first].ins(x,e.second);
}
}else{
a.d+=d;
for(int y:h[k^1]){
auto&b=f[k^1][y];
auto i=b.w.find(x);
if(b.w.end()!=i){
i->second+=d;
upd2(b.s,i->second+b.d);
}
}
}
a.s+=d;
}
void sol4(int k,int x,int nx){
g[k][nx]=g[k][x];
g[k].erase(x);
}
void sol3(int k,int x,int nx){
auto&a=f[k][x],&b=f[k][nx];
if(h[k].end()==h[k].find(x))
dev(k,x);
for(auto e:a.w){
auto&c=f[k^1][e.first];
upd2(c.w[nx],e.second+a.d-c.d);
c.w.erase(x);
b.ins(e.first,e.second+a.d);
}
if(h[k].erase(x)||b.w.size()>n2){
h[k].insert(nx);
dev(k,nx);
}
}
void sol2(int k,int x,int nx){
sol3(k,g[k][x],g[k][nx]);
g[k].erase(x);
}
void sol1(int k,int x,int nx){
if(f[k][g[k][x]].w.size()<=f[k][g[k][nx]].w.size())
sol2(k,x,nx);
else{
sol2(k,nx,x);
sol4(k,x,nx);
}
}
void mov(int k,int x,int nx){
if(x!=nx)
(g[k].end()!=g[k].find(nx)?sol1:sol4)(k,x,nx);
}
int main(){
int n,m,x,y,d;
char o[8];
scanf("%d",&n);
n2=sqrt(n+.5);
while(n--){
scanf("%d%d%d",&x,&y,&d);
f[0][x].ins(y,d);
f[1][y].ins(x,d);
g[0][x]=x;
g[1][y]=y;
}
for(int k=0;k<2;++k)
for(auto&e:f[k])
if(e.second.w.size()>n2)
h[k].insert(e.first);
scanf("%d",&m);
while(m--){
scanf("%s%d",o,&x);
int k=*o=='Y';
if(o[1]=='Q')
printf("%d\n",ask(k,x));
else{
scanf("%d",&d);
if(g[k].end()!=g[k].find(x))
o[1]=='M'?mov(k,x,x+d):inc(k,g[k][x],d);
}
}
}

UOJ309 UNR #2 排兵布阵的更多相关文章

  1. HDU 4539郑厂长系列故事――排兵布阵(状压DP)

    HDU 4539  郑厂长系列故事――排兵布阵 基础的状压DP,首先记录先每一行可取的所哟状态(一行里互不冲突的大概160个状态), 直接套了一个4重循环居然没超时我就呵呵了 //#pragma co ...

  2. HDU 4539 郑厂长系列故事——排兵布阵

    http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others) ...

  3. 郑厂长系列故事——排兵布阵 hdu4539(状态压缩DP)

    郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  4. [BJOI2019]排兵布阵——分组背包

    题目链接: [BJOI2019]排兵布阵 对于每座堡垒,将$s$个对手排序,显然如果安排的兵力能打败第$i$个对手就一定能打败前$i-1$个. 那么对于第$i$座城堡,可以看做有$s+1$个物品(可以 ...

  5. [BJOI2019]排兵布阵(动态规划)

    [BJOI2019]排兵布阵(动态规划) 题面 洛谷 题解 暴力dp: 设\(f[i][j]\)表示考虑到了第\(i\)座城市用了\(j\)人的最大收益,枚举在这个城市用多少人就可以了. 优化: 发现 ...

  6. HDU-4539郑厂长系列故事——排兵布阵(状态压缩,动态规划)

    郑厂长系列故事--排兵布阵 Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total ...

  7. HDU 4539 郑厂长系列故事——排兵布阵 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事--排兵布阵 Time Limit: 10000/5000 MS (Java/O ...

  8. HDU 4539 郑厂长系列故事——排兵布阵 —— 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Ot ...

  9. 洛谷 P1911 L国的战斗之排兵布阵

    P1911 L国的战斗之排兵布阵 题目背景 L国即将与I国发动战争!! 题目描述 L国的指挥官想让他的每一个军营都呈现出国徽形——“L”形(方向无所谓).当然,他的指挥营除外(这叫做个性),他想不出该 ...

随机推荐

  1. UnicodeEncodeError: 'ascii' codec can't encode character u'\u5728' in position 1

    s = "图片picture"print chardet.detect(s) for c in s.decode('utf-8'): print c UnicodeEncodeEr ...

  2. 什么是猴子补丁(monkey patch)

    monkey patch指的是在执行时动态替换,通常是在startup的时候. 用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all();把标准库中的thread/ ...

  3. HAProxy简单使用

    一.HAProxy简介及定位         HAProxy 是一款基于TCP和HTTP应用的具备高可用行且负载均衡的代理软件.HAProxy是完全免费的,借助HAProxy可以快速.可靠地提供基于T ...

  4. python去除停用词(结巴分词下)

    python 去除停用词  结巴分词 import jieba #stopwords = {}.fromkeys([ line.rstrip() for line in open('stopword. ...

  5. centos创建本地yum仓库

    怎样发布自己软件的安装和更新YUM源 在创建之前,我们先了解些相关的内容: yum仓库可以支持三种途径提供给yum在安装的时候下载rpm包 第一种:  ftp服务  ftp:// 第二种:  http ...

  6. LeetCode:判断最长前缀

    之前一直忽略了一个问题就是:给定的空字符串数组 char* longestCommonPrefix(char** strs, int strsSize) { char* result; if(strs ...

  7. 第一个php小程序(学习)

    </pre><pre name="code" class="php"><? php $b=array("name&quo ...

  8. javascript 返回上一页面

    <a href="<a href="javascript :history.back(-1)">返回上一页</a>或<a href=& ...

  9. new和delete的基本用法

    前言 new和delete是C++中用来动态管理内存分配的运算符,其用法较为灵活.如果你对它们的几种不同用法感到困惑,混淆,那么接着看下去吧. 功能一:动态管理单变量/对象空间 下面例子使用new为单 ...

  10. throws ? catch checked unchecked

    ThrowableClass Error  (unchecked) Exception IOException (checked) RuntimeException (unchecked) publi ...