首页 > 其他分享 >2024-04-02

2024-04-02

时间:2024-04-02 21:25:03浏览次数:26  
标签:02 const 04 idx int 2024 dep include hd

2024-04-02

作业

莫队+值域分块

维护区间内每个数出现的次数,块内出现的总次数,块内符合要求的数值数

卡了一会的问题是:
我写分块习惯把每个点所在的块和每一块的左右端点提前求出来而不是现场算
这时如果询问的值域比数列的值域大
上面那些值都是没有定义的
就寄了

所以要把询问的右端点和数列的值域取个 \(\min\)

但是这样有可能导致 \(b<a\) 于是又寄了,要判断一下

又是好智障的错啊,太影响效率了

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;

const int N=100100,M=333;
const int Inf=2e9;

int n,m;
int w[N];
int L,len,V;
int blk[N],lft[M],rgh[M];

struct Qry {
	int id;
	int l,r,a,b;
	#define B(x) ((x-1)/L+1)
	bool operator< (const Qry &t)const {
		if(B(l)==B(t.l)) return r<t.r;
		return B(l)<B(t.l);
	}
}qry[N];

struct Ans {
	int ans1,ans2;
}ans[N];

int cnt[N],grp[M],num[M];

void add(int x) {
	cnt[x]++;
	grp[blk[x]]++;
	if(cnt[x]==1) num[blk[x]]++;
}

void del(int x) {
	cnt[x]--;
	grp[blk[x]]--;
	if(cnt[x]==0) num[blk[x]]--;
}

Ans query(int a,int b) {
	b=min(b,V);
	Ans res;
	res.ans1=res.ans2=0;
	if(b<a) return res;
	if(blk[a]==blk[b]) {
		for(int i=a;i<=b;i++) if(cnt[i]) res.ans1+=cnt[i],res.ans2++;
		return res;
	}
	for(int i=blk[a]+1;i<=blk[b]-1;i++) {
		res.ans1+=grp[i];
		res.ans2+=num[i];
	}
	for(int i=a;i<=rgh[blk[a]];i++) if(cnt[i]) res.ans1+=cnt[i],res.ans2++;
	for(int i=lft[blk[b]];i<=b;i++) if(cnt[i]) res.ans1+=cnt[i],res.ans2++;
	return res;
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&w[i]),V=max(V,w[i]);
	L=sqrt(n),len=sqrt(V);
	for(int i=1;i<=V;i++) blk[i]=(i-1)/len+1,lft[blk[i]]=Inf,rgh[blk[i]]=-Inf;
	for(int i=1;i<=V;i++) lft[blk[i]]=min(lft[blk[i]],i),rgh[blk[i]]=max(rgh[blk[i]],i);
	for(int i=1;i<=m;i++) {
		qry[i].id=i;
		int l,r,a,b; 
		scanf("%d%d%d%d",&l,&r,&a,&b);
		qry[i].l=l,qry[i].r=r,qry[i].a=a,qry[i].b=b;
	}
	sort(qry+1,qry+m+1);
	int hd=0,tl=1;
	for(int i=1;i<=m;i++) {
		int l=qry[i].l,r=qry[i].r;
		while(tl>l) add(w[--tl]);
		while(hd<r) add(w[++hd]);
		while(tl<l) del(w[tl++]);
		while(hd>r) del(w[hd--]);
		ans[qry[i].id]=query(qry[i].a,qry[i].b);
	}
	for(int i=1;i<=m;i++) printf("%d %d\n",ans[i].ans1,ans[i].ans2);
	
	return 0;
} 

今天状态太差了

下午听课还行
但是一整天就写了一道题

写回滚莫队调了好长时间不对,气急败坏直接抄题解,但是罪恶感迫使我准备之后再看看

晚上提前回去,做了一半的题

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

const int V=600,E=20000;
const int N=V*2+100,M=2*(2*V+V*V+100);
const int Inf=1e8;

int n,m;
int key;
int num,cnt[V];

int dis[V][V];

int hd[N],edg[M],nxt[M],cap[M],idx;
int cur[N],dep[N];
int s,t;

void adde(int u,int v,int w) {
	edg[idx]=v,cap[idx]=w,nxt[idx]=hd[u],hd[u]=idx++;
	edg[idx]=u,cap[idx]=0,nxt[idx]=hd[v],hd[v]=idx++;
}

bool bfs() {
	memset(dep,-1,sizeof(dep));
	queue<int> q;
	dep[s]=0,cur[s]=hd[s];
	q.push(s);
	while(!q.empty()) {
		int u=q.front();
		q.pop();
		for(int i=hd[u];~i;i=nxt[i]) {
			int v=edg[i];
			if(dep[v]==-1&&cap[i]) {
				dep[v]=dep[u]+1;
				cur[v]=hd[v];
				if(v==t) return true;
				q.push(v);
			}
		}
	}
	return false;
}

int dfs(int u,int lim) {
	if(u==t) return lim;
	int flw=0;
	for(int i=cur[u];~i&&flw<lim;i=nxt[i]) {
		cur[u]=i;
		int v=edg[i];
		if(dep[v]==dep[u]+1&&cap[i]) {
			int tmp=dfs(v,min(cap[i],lim-flw));
			if(!tmp) dep[v]=-1;
			cap[i]-=tmp,cap[i^1]+=tmp;
			flw+=tmp;
		}
	}
	return flw;
}

int dinic() {
	int res=0,flw;
	while(bfs()) while(flw=dfs(s,Inf)) res+=flw;
	return res;
}

void build(int lim) {
	idx=0;
	memset(hd,-1,sizeof(hd));
	s=0,t=2*n+1;
	for(int u=1;u<=n;u++)
		for(int v=1;v<=n;v++)
			if(dis[u][v]<=lim) adde(u,v+n,Inf);
	for(int u=1;u<=n;u++){
		if(cnt[u]) adde(s,u,cnt[u]);
		adde(u+n,t,1);
	}
}

bool check(int lim) {
	build(lim);
	int res=dinic();
	cout<<lim<<' '<<res<<endl;
	return res>=key;
}

int main() {
	scanf("%d%d%d%d",&n,&m,&num,&key);
	for(int i=1;i<=num;i++) {
		int pos;
		scanf("%d",&pos);
		cnt[pos]++;
	}
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=m;i++) {
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		dis[u][v]=dis[v][u]=w;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=j) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int lft=0,rgh=1731311,ans;
	if(!check(rgh)) {
		puts("-1");
		return 0;
	}
	while(lft<rgh) {
		int mid=lft+rgh>>1;
		if(check(mid)) ans=mid,rgh=mid-1;
		else lft=mid+1;
	}
	printf("%d\n",ans);
	
	return 0;
} 

标签:02,const,04,idx,int,2024,dep,include,hd
From: https://www.cnblogs.com/Orange-Star/p/18109845

相关文章

  • 20240402打卡
    第六周第一天第二天第三天第四天第五天第六天第七天所花时间3h4h代码量(行)122146博客量(篇)11知识点了解个人网站搭建完成结组团队开发......
  • 2024年AI订阅、游戏消费、流媒体订阅、域名购买等常用的美元信用卡使用场景科普大全!
    应用场景卡BIN详细应用AI软件支付534786、556150虚拟信用卡用于支付AI软件订阅,如ChatGPTPlus、OpenAI-APIKey、Midjourney、POE等。电商网站购物559666、531993适用于Amazon、Ebay、Etsy、Alibaba、Shopify、Walmart、TikTok、AliExpress、Lazada、Rakuten、Wish、BestBuy、......
  • P7219 [JOISC2020] 星座 3【笛卡尔树+整体dp】
    P7219[JOISC2020]星座3笛卡尔树+整体dp(线段树合并维护dp)考虑转化题意,不存在矩形为星座,即对于每个极大矩形中都只有一颗星星。而观察题目的方格,对于两个位置是否能够成为一个矩形,只和两个位置的区间最大值(小白船的位置)有关①。图中的红蓝矩形即为两个极大矩形。将删除星......
  • L3-002 特殊堆栈
    维护两个栈。一个正常放数据,另一个是排序好的数据。#include<bits/stdc++.h>usingnamespacestd;intmain(){ vector<int>data; vector<int>mdata; vector<int>::iteratorit; intn; cin>>n; while(n--){strings; cin>>s; if(s==......
  • 2024-4-2日 记
    又到了4月1,本来没想着写的,但是看了看22年,23年,今年也想来写一些东西,记录一下自己的感悟。22年的4月1,因为考研失败,也没找到好工作,被前女友嫌弃,人生跌落谷底。23年的4月1,因为考研调剂复试,也不知道什么结果,很可能没有学上,人生走向拐点。24年的4月1,已经是研一,确定了研究方向,很好的导......
  • smu2024蓝桥杯训练1
    A[语言月赛202401]装满葡萄汁的酒杯查看代码voidsolve(){intn;cin>>n;if(n<=100)cout<<100;elseif(n<=150)cout<<150;elseif(n<=300)cout<<300;elseif(n<=400)cout<<400;e......
  • 每日收获2024/4/2
    Python路径:安装模块用pip,但是path路径可能不放其所在的script路径,所以要找到python/path路径安装模块Windows环境变量进入方法:crtl+delete进入任务管理器,新建任务,输入sysdm.cpl,进入到环境变量配置页面C语言中的Static用法:static静态变量(只能在本文件中使用),在运行时只在开始赋......
  • 2024 数据技术嘉年华 | 狂欢嘉年华,好礼送不停!
    狂欢嘉年华,好礼送不停!......
  • Ubuntu 23.04 安装es
    在Ubuntu23.04上安装Elasticsearch的过程可能与之前版本类似,以下是基于最新稳定版Elasticsearch的一般安装步骤:准备工作:确保系统已更新至最新版本:sudoaptupdate&&sudoaptupgrade安装JavaDevelopmentKit(JDK)。Elasticsearch至少需要Java11。可以通过官方......
  • 小美的树上染色(美团2024届秋招笔试第一场编程真题)
    题面核心思想树形DPdp[1]表示以当前节点为根节点所包含的子树且当前节点能染色的最大染色数量dp[0]表示以当前节点为根节点所包含的子树且当前节点不染色的最大染色数量详情看注释~代码importjava.util.*;publicclassMain{publicstaticvoidmain(String[......