D1T1:与或和

对每位处理,问题变成所有内部不包含0/1的矩阵的个数,单调栈维护即可。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,mod=1e9+;
int top,sum,sm,n,mx,a[N][N],b[N][N],st[N],sz[N],l[N][N]; int work(int w,int op){
rep(i,,n) rep(j,,n)
if((a[i][j]&(<<w))) b[i][j]=op; else b[i][j]=op^;
rep(i,,n){
l[i][n]=b[i][n];
for(int j=n-; j; j--)
if(!b[i][j]) l[i][j]=; else l[i][j]=l[i][j+]+;
}
int tmp=;
rep(j,,n){
top=,sum=;
rep(i,,n){
int now=;
while (top && st[top]>=l[i][j])
sum-=st[top]*sz[top],now+=sz[top],top--;
st[++top]=l[i][j]; sz[top]=now+;
sum+=st[top]*sz[top]; tmp=(tmp+sum)%mod;
}
}
return tmp;
} int main(){
freopen("andorsum.in","r",stdin);
freopen("andorsum.out","w",stdout);
scanf("%d",&n);
rep(i,,n) rep(j,,n) scanf("%d",&a[i][j]),mx=max(mx,a[i][j]);
rep(i,,n) rep(j,,n) sm=(sm+1ll*i*j)%mod;
int ans1=,ans2=;
rep(w,,){
if ((1ll<<w)>mx) break;
int t=(1ll<<w)%mod;
ans1=(ans1+1ll*t*work(w,)%mod)%mod;
ans2=(ans2+1ll*t*(sm-work(w,)+mod)%mod)%mod;
}
printf("%d %d\n",ans1,ans2);
return ;
}

andorsum

D1T3:特技飞行

被观察到的特技次数是固定的,先曼哈顿转切比雪夫然后KDT统计即可。

然后发现,若所有特技全部选择对向交换,一定是符合要求的,于是得到了两个极值中的一个。

接下来要让对向交换的次数尽量小,也就是给两个排列,让第一个经过最小的交换次数变成第二个。

找出置换环,答案就是n-置换环数。

 #include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
const double eps=1e-,inf=1e13;
ll A,B,C;
int n,T,tot,st,ed,x,y,rr,y0[N],y1[N],id[N],vis[N],b[N],cov[N];
set<pair<int,int> >S;
set<pair<int,int> >::iterator it; struct P{ double v[],mn[],mx[]; int ls,rs; }v[N],t;
bool cmpx(const P &a,const P &b){ return a.v[]<b.v[]; }
bool cmpy(const P &a,const P &b){ return a.v[]<b.v[]; }
bool cmp(int a,int b){ return y1[a]<y1[b]; } double Abs(double x){ return x< ? -x : x; } void upd(int x){
rep(i,,){
v[x].mn[i]=min(v[x].v[i],min(v[v[x].ls].mn[i],v[v[x].rs].mn[i]));
v[x].mx[i]=max(v[x].v[i],max(v[v[x].ls].mx[i],v[v[x].rs].mx[i]));
}
} int build(int L,int R,int k){
if (L>R) return ;
int mid=(L+R)>>,x=mid;
nth_element(v+L,v+mid,v+R+,k?cmpy:cmpx);
v[x].ls=build(L,mid-,k^); v[x].rs=build(mid+,R,k^);
upd(x); return x;
} void mdf(int x){
if (!x || b[x] || t.v[]+rr<v[x].mn[] || t.v[]-rr>v[x].mx[] || t.v[]+rr<v[x].mn[] || t.v[]-rr>v[x].mx[]) return;
double s=;
rep(i,,) s=max(s,max(Abs(t.v[i]-v[x].mn[i]),Abs(t.v[i]-v[x].mx[i])));
if (s-eps<rr){ b[x]=; return; }
if (!cov[x] && max(Abs(v[x].v[]-t.v[]),Abs(v[x].v[]-t.v[]))-eps<rr) cov[x]=;
mdf(v[x].ls); mdf(v[x].rs);
} int dfs(int x){
if (b[x]) cov[x]=cov[v[x].ls]=cov[v[x].rs]=b[v[x].ls]=b[v[x].rs]=;
int res=cov[x];
if (v[x].ls) res+=dfs(v[x].ls);
if (v[x].rs) res+=dfs(v[x].rs);
return res;
} int main(){
freopen("aerobatics.in","r",stdin);
freopen("aerobatics.out","w",stdout);
v[].mn[]=v[].mn[]=inf; v[].mx[]=v[].mx[]=-inf;
scanf("%d%lld%lld%lld%d%d",&n,&A,&B,&C,&st,&ed);
rep(i,,n) scanf("%d",&y0[i]);
rep(i,,n) scanf("%d",&y1[i]);
for (int i=n; i; i--){
for (it=S.begin(); it!=S.end() && (it->first<y1[i]); it++){
int j=it->second;
double t=(double)(y0[j]-y0[i])/(y1[i]-y1[j]);
double x=(t*ed+st)/(t+),y=(t*y1[j]+y0[j])/(t+);
v[++tot].v[]=x+y; v[tot].v[]=x-y;
}
S.insert(pair<int,int>(y1[i],i));
}
int rt=build(,tot,);
for (scanf("%d",&T); T--; )
scanf("%d%d%d",&x,&y,&rr),t.v[]=x+y,t.v[]=x-y,mdf(rt);
ll ans=dfs(rt)*C,ans1=ans+tot*A,ans2=ans+tot*A;
rep(i,,n) id[i]=i;
sort(id+,id+n+,cmp);
ll x=n;
rep(i,,n) if (!vis[i]){
x--;
for (int j=i; !vis[j]; j=id[j]) vis[j]=;
}
ans2+=(tot-x)*(B-A);
printf("%lld %lld\n",min(ans1,ans2),max(ans1,ans2));
return ;
}

aerobatics

D2T2:旅行者

方法一:二进制分组,对每个二进制位,将所有编号在这一位为0的关键点放在一边,为1的放在另一边跑最短路。这样任意两点间最短路都一定在某次中被考虑到。O(nlog^2n)

 #include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=,inf=1e9;
int n,m,k,T,u,v,w,ans,cnt,s[N],b[N],dis[N],fr[N],h[N],to[N],nxt[N],val[N];
struct P{ int x,d; };
bool operator <(const P &a,const P &b){ return a.d>b.d; }
priority_queue<P>Q; void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; } void dij(){
while (!Q.empty()){
int x=Q.top().x; Q.pop();
if (b[x]) continue;
b[x]=;
For(i,x) if (dis[k=to[i]]>dis[x]+val[i])
dis[k]=dis[x]+val[i],fr[k]=fr[x],Q.push((P){k,dis[k]});
}
} int main(){
freopen("tourist.in","r",stdin);
freopen("tourist.out","w",stdout);
for (scanf("%d",&T); T--; ){
cnt=; ans=inf; rep(i,,n) h[i]=;
scanf("%d%d%d",&n,&m,&k);
rep(i,,m) scanf("%d%d%d",&u,&v,&w),add(u,v,w);
rep(i,,k) scanf("%d",&s[i]);
for (int t=; t<=k; t<<=){
rep(i,,n) dis[i]=inf,b[i]=;
while (!Q.empty()) Q.pop();
rep(i,,k) if (i&t) dis[s[i]]=,Q.push((P){s[i],}),fr[s[i]]=s[i];
dij();
rep(i,,k) if (!(i&t)) ans=min(ans,dis[s[i]]);
rep(i,,n) dis[i]=inf,b[i]=;
while (!Q.empty()) Q.pop();
rep(i,,k) if (!(i&t)) dis[s[i]]=,Q.push((P){s[i],}),fr[s[i]]=s[i];
dij();
rep(i,,k) if (i&t) ans=min(ans,dis[s[i]]);
}
printf("%d\n",ans);
}
return ;
}

方法一

方法二:对于一条边,它对答案的贡献是a[u]+w+b[v],其中a是所有关键点到它的最短距离,b是它到所有关键点的最短距离。

注意若a和b来自同一个关键点的时候忽略这条边,显然任意两个关键点之间的最短路上总有一条边不会被忽略。O(nlogn)

 #include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=,inf=1e9;
int n,m,k,T,u,v,w,ans,s[N],b[N];
struct P{ int x,d; };
bool operator <(const P &a,const P &b){ return a.d>b.d; }
priority_queue<P>Q;
struct E{ int u,v,w; }e[N]; struct Gr{
int cnt,dis[N],fr[N],h[N],to[N],nxt[N],val[N];
void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; } void dij(){
rep(i,,n) dis[i]=inf,b[i]=;
while (!Q.empty()) Q.pop();
rep(i,,k) dis[s[i]]=,Q.push((P){s[i],}),fr[s[i]]=s[i];
while (!Q.empty()){
int x=Q.top().x; Q.pop();
if (b[x]) continue;
b[x]=;
For(i,x) if (dis[k=to[i]]>dis[x]+val[i])
dis[k]=dis[x]+val[i],fr[k]=fr[x],Q.push((P){k,dis[k]});
}
}
}G1,G2; void init(){
G1.cnt=G2.cnt=; ans=inf;
memset(G1.h,,sizeof(G1.h)); memset(G2.h,,sizeof(G2.h));
} int main(){
freopen("tourist.in","r",stdin);
freopen("tourist.out","w",stdout);
for (scanf("%d",&T); T--; ){
init(); scanf("%d%d%d",&n,&m,&k);
rep(i,,m) scanf("%d%d%d",&u,&v,&w),G1.add(u,v,w),G2.add(v,u,w),e[i]=(E){u,v,w};
rep(i,,k) scanf("%d",&s[i]);
G1.dij(); G2.dij();
rep(i,,m) if (G1.fr[e[i].u]!=G2.fr[e[i].v]) ans=min(ans,G1.dis[e[i].u]+e[i].w+G2.dis[e[i].v]);
printf("%d\n",ans);
}
return ;
}

方法二

GXOI/GZOI2019部分题解的更多相关文章

  1. GXOI/GZOI2019题解

    GXOI/GZOI2019题解 P5300 [GXOI/GZOI2019]与或和 一眼题.. 显然枚举每个二进制位,答案就变成了全1子矩阵数量. 这个xjb推推,单调栈一下就行了. #include& ...

  2. 「GXOI / GZOI2019」简要题解

    「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...

  3. 题解-GXOI/GZOI2019 特技飞行

    Problem loj3085 bzoj不放题面差评 题意概要:给出两条竖直直线,再给出 \(n\) 架飞机的初始航线:一条接通这两条直线的线段,保证航线交点不在两条直线上.现要求安排所有飞机在航线相 ...

  4. 【BZOJ5505】[GXOI/GZOI2019]逼死强迫症(矩阵快速幂)

    [BZOJ5505][GXOI/GZOI2019]逼死强迫症(矩阵快速幂) 题面 BZOJ 洛谷 题解 如果没有那两个\(1*1\)的东西,答案就是斐波那契数,可以简单的用\(dp\)得到. 大概是设 ...

  5. P5305 [GXOI/GZOI2019]旧词

    题目地址:P5305 [GXOI/GZOI2019]旧词 这里是官方题解 \[\sum_{i \leq x}^{}\ depth(lca(i,y))^k\] \(k = 1\) 求的是 \(\sum_ ...

  6. P5304 [GXOI/GZOI2019]旅行者

    题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...

  7. P5303 [GXOI/GZOI2019]逼死强迫症

    题目地址:P5303 [GXOI/GZOI2019]逼死强迫症 这里是官方题解 初步分析 从题目和数据范围很容易看出来这是一个递推 + 矩阵快速幂,那么主要问题在于递推的过程. 满足条件的答案一定是以 ...

  8. P5302 [GXOI/GZOI2019]特技飞行

    题目地址:P5302 [GXOI/GZOI2019]特技飞行 这里是官方题解(by lydrainbowcat) 题意 给 \(10^5\) 条直线,给 \(x = st\) 和 \(x = ed\) ...

  9. P5301 [GXOI/GZOI2019]宝牌一大堆

    题目地址:P5301 [GXOI/GZOI2019]宝牌一大堆 这里是官方题解(by lydrainbowcat) 部分分 直接搜索可以得到暴力分,因为所有和牌方案一共只有一千万左右,稍微优化一下数据 ...

随机推荐

  1. useState 的介绍和多状态声明(二)

    useState的介绍 useState是react自带的一个hook函数,它的作用是用来声明状态变量. 那我们从三个方面来看useState的用法,分别是声明.读取.使用(修改).这三个方面掌握了, ...

  2. SQLServer stuff函数

    STUFF ( character_expression , start , length ,character_expression ) 参数 character_expression 一个字符数据 ...

  3. Tosca :配置环境参数

    # 跟Modules TestCases并列 ,右键创建 #再右键创建配置(结构自己安排) #再创建配置参数 #使用配置参数 #引用配置的环境参数

  4. Git 回滚 Master

    RenGuoQiang@PC-RENGUOQIANG MINGW64 /d/zgg/zgg-crm (master) $ git reset --hard 194e2cc8eec88743cc8978 ...

  5. PHP 输出日志到文件 DEMO

    首先需要确保输出文件有权限写入,一般设置权限为 chown -R nginx.nginx 输出的文件路径 如果以上方法还是无效,可以直接将文件设置有777,但是这种方式只能用于测试环境 chmod - ...

  6. Kotlin介绍

    Kotlin介绍 转 https://www.jianshu.com/p/d30406daaf25 Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Goo ...

  7. SegNet

    Paper link:https://arxiv.org/pdf/1511.00561.pdf Motivation:为了实际应用,主要是在时间效率和存储空间上做了改进: Introduction: ...

  8. Can't accept UDP connections java.net.BindException: Address already in use_解决方案

    一.问题描述 在Linux服务器(CentOS7系统)中配置并启动JMeter远程监控服务器资源所需的ServerAgent目录下的 startAgent.sh 文件时,系统出现异常提示,如下: [r ...

  9. ubuntu18.04安装DB2 11.1 Express-c

    参考连接:https://developer.ibm.com/answers/questions/280797/download-db2-express-c-105-1/ 这个参考页面提供了DB2 E ...

  10. html 图标和文字一行对齐

    原图: 效果图: 备注:vertical-align:middle <div> <p class="time tl-size12" style="pad ...