CSP模拟18 [求助求助!T3调不出]
【签到】T1:给出[L,R]区间,求最长链,使得任意十进制表示的数字不出现包含关系(连续)。(R<=1e9)
相当于最少的链覆盖,使得每组的数字都是覆盖的,从大到小筛出不同的组有多少。发现R固定,对于下接,是来自\(L,(R/10),R去掉最高位\)的max,O(1)确定
点击查看代码
//慎独,深思,毋躁,自律,专注,勿生妄念,极致,不念过往,不放当下
#include<bits/stdc++.h>
using namespace std;
#define chu printf
#define _f(i,a,b) for(register int i=(a);i<=(b);++i)
#define f_(i,a,b) for(register int i=(a);i>=(b);--i)
#define inf 2147483647
#define ll long long
#define rint register int
#define ull unsigned long long
inline ll re()
{
ll x=0,h=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')h=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*h;
}
const int N=-1;
ll L,R,pw[20];
int T;
inline int Count(ll x)
{
int bit=0;
while(x)
{
bit++;x/=10;
}
return bit;
}
int main()
{
//freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
T=re();
pw[0]=1;
pw[1]=10;
_f(i,2,15)pw[i]=pw[i-1]*10ll;
while(T--)
{
L=re(),R=re();
int bl=Count(L),br=Count(R);
if(bl==br)
{
chu("%lld\n",R-L+1);
}
else
{
ll ls=R;
while(ls>=10)ls/=10;
if(ls>1)
{
chu("%lld\n",R-pw[br-1]+1);
}
else
{
ll del1=0;
ls=R;
ls/=10;
ls%=pw[br-1];
del1=ls;
ll del2=R%pw[br-1];
// chu("del1:%lld del2:%lld L-1:%lld\n",del1,del2,L-1);
chu("%lld\n",R-max({del2,del1,L-1}));
}
}
}
return 0;
}
/*
1
115 111111108
3
3 8
3 18
1 1000
1
83 1068
*/
【结论,规律/暴力】T2:给出一段序列,可以对每个数进行任意次操作,\(Ai=2*Ai+x\),求max-min的最小值。(n<=1e5)
暴力
发现对于给定的序列,答案是maxl-minr,放进set,每次取出minr操作+1,直到取到最优答案或者时间不够为止.
set会慢,用优先队列
点击查看代码
//慎独,深思,毋躁,自律,专注,勿生妄念,极致,不念过往,不放当下
#include<bits/stdc++.h>
#include<chrono>
using namespace std;
using namespace std::chrono;
#define chu printf
#define _f(i,a,b) for(register int i=(a);i<=(b);++i)
#define f_(i,a,b) for(register int i=(a);i>=(b);--i)
#define inf 2147483647
#define ll long long
#define rint register int
#define ull unsigned long long
inline ll re()
{
ll x=0,h=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')h=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*h;
}
const int N=1e5+100;
struct Ele
{
ll fir,sec;
int sel,sig;
bool operator<(const Ele&U)const
{
return fir<U.fir;
}
}t1,t2,t3;
multiset<Ele>lp,rp;
int n,num[N];
ll lim,val[N];
int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
auto T1=steady_clock::now();
n=re();lim=re();
ll minn=1e17,maxx=-1e17;
_f(i,1,n)
{
val[i]=re();
minn=min(minn,val[i]);
maxx=max(maxx,val[i]);
}
ll ans=maxx-minn;
_f(i,1,n)
{
lp.insert((Ele){val[i],val[i],i,0});
rp.insert((Ele){val[i],val[i],i,0});
}
while(1)
{
auto T2=steady_clock::now();
auto T3=duration_cast< duration<double,ratio<1,1000> > >(T2-T1);
if(T3.count()>900) break;
t2=*rp.begin();
if(t2.fir>1e18)break;
//r min
num[t2.sel]++;
rp.insert((Ele){t2.fir*2+lim,t2.sec*2,t2.sel,num[t2.sel]});
lp.insert((Ele){t2.sec*2,t2.fir*2+lim,t2.sel,num[t2.sel]});
rp.erase(t2);
//lp.erase((Ele){t2.sec,t2.fir});
t1=*lp.rbegin();
while(num[t1.sel]!=t1.sig)
{
lp.erase(t1);
t1=*lp.rbegin();
}
t2=*rp.begin();
//chu("(%lld %lld )(%lld %lld)\n",t1.fir,t1.sec,t2.fir,t2.sec);
ans=min(ans,max(0ll,t1.fir-t2.fir));
if(!ans)break;
}
chu("%lld",ans);
return 0;
}
/*
*/
点击查看代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<queue>
#include<set>
#include<chrono>
using namespace std::chrono;
using namespace std;
const int N=100010;
inline int read()
{
int x=0,f=1; char c;
while(!isdigit(c=getchar())) if(c=='-') f=-1;
do x=(x<<1)+(x<<3)+(c^48); while(isdigit(c=getchar()));
return x*f;
}
int H,lim;
long long val[N],minn,vala,valb;
int num[N];
struct Let { long long fir,sec; int sel,sig; };
struct Ret { long long fir,sec; int sel,sig; };
inline bool operator <(const Let A,const Let B){ return A.fir<B.fir; }
inline bool operator >(const Ret A,const Ret B){ return A.fir>B.fir; }
priority_queue<Let,vector<Let>,less<Let> >let;
priority_queue<Ret,vector<Ret>,greater<Ret> >ret;
signed main()
{
auto T1=steady_clock::now();
H=read(); lim=read(); vala=-2e9; valb=2e9;
for(int i=1;i<=H;i++) val[i]=read(),vala=max(vala,val[i]),valb=min(valb,val[i]);
for(int i=1;i<=H;i++)
let.push((Let){val[i],val[i],i,0}),ret.push((Ret){val[i],val[i],i,0});
minn=vala-valb;
while(1)
{
auto T2=steady_clock::now();
auto T3=duration_cast< duration<double,ratio<1,1000> > >(T2-T1);
if(T3.count()>900) break;
Ret now=ret.top(); ret.pop();
if(now.fir>1e18) break; ++num[now.sel];
ret.push((Ret){now.fir*2ll+lim,now.sec*2ll,now.sel,num[now.sel]});
let.push((Let){now.sec*2ll,now.fir*2ll+lim,now.sel,num[now.sel]});
while(let.top().sig!=num[let.top().sel]) let.pop();
minn=min(minn,max(0ll,let.top().fir-ret.top().fir));
if(!minn) break;
}
printf("%lld\n",minn);
return 0;
}
【】T3:无向图,每个点有(s,t,c)权值,如果从a-->b,要求经过的c_road_of_a<t_b,求每个点出发最大的s。(n<=1e5)
暴力
直接sort s,从大到小,每次拿出来一个点跑,如果所有点都更新过了直接break(不会有更优的答案了)。
这里的vis是不能打的,因为我更新了这个点,从其他点更新到这个点使得它具有的值,可能会更优,所以考虑什么时候可以用st更新to,如果此时ans[to]<item(起点的s),不一定不优,因为t的下界松了,如果此时minnt<last_minnt也不一定,因为ans可能更优;那么2个都不满足一定就不用进去了,这样不用vis,因为一次完全遍历后,ans一定不会有更优的答案了,而t因为mt一直记录更新当前点的最松下界,所以也不满足条件了。
但是问题是!!!!
为什么BFS不对但是DFS就对?其他的都没变,就是把DFS传的参数变成了BFS的minnt数组,minnt数组我就用mt代替了,但是就是不对。
错误代码:(40分,小数据过不了,答案偏小)
点击查看代码
//慎独,深思,毋躁,自律,专注,勿生妄念,极致,不念过往,不放当下
#include<bits/stdc++.h>
using namespace std;
#define chu printf
#define _f(i,a,b) for(register int i=(a);i<=(b);++i)
#define f_(i,a,b) for(register int i=(a);i>=(b);--i)
#define inf 2147483647
#define ll long long
#define rint register int
#define ull unsigned long long
inline ll re()
{
ll x=0,h=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')h=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*h;
}
const int N=2e5+100;
int head[N],tot,n,m;
int ans[N],rem[N],hsv,rk[N],mt[N],minnt[N],vs[N];
bool ar[N];
deque<int>stk;
struct Node
{
int to,nxt;
}e[N<<1];
struct Mess
{
int s,c,t,id;
bool operator<(const Mess&U)const
{
return s>U.s;
}
}dot[N];
inline void Add(int x,int y)
{
e[++tot].to=y;
e[tot].nxt=head[x];
head[x]=tot;
}
inline void BFS(int st,int item,int lim)
{
_f(i,1,rem[0])minnt[rem[i]]=dot[rk[rem[i]]].t,vs[rem[i]]=0;
rem[0]=0;
rem[++rem[0]]=st;
stk.push_front(st);
ans[st]=max(ans[st],item);
if(!ar[st])
{
ar[st]=1;hsv++;
}
vs[st]=1;
while(!stk.empty())
{
int top=stk.front();stk.pop_front();vs[top]=0;
for(rint i=head[top];i;i=e[i].nxt)
{
int to=e[i].to;
//vis清空!
if(dot[rk[to]].c>minnt[top])continue;
if(ans[to]<item||mt[to]<minnt[top])
{
ans[to]=max(ans[to],item);
mt[to]=max(mt[to],minnt[top]);
minnt[to]=min(dot[rk[to]].t,minnt[top]);
rem[++rem[0]]=to;
if(!ar[to])
{
ar[to]=1;hsv++;
}
if(!vs[to]) stk.push_back(to),vs[to]=1;
}
}
}
}
int main()
{
//freopen("1.in","r",stdin);
// freopen("2.out","w",stdout);
n=re(),m=re();
_f(i,1,n)dot[i].c=re(),dot[i].t=re(),dot[i].s=re(),dot[i].id=i;
_f(i,1,m)
{
int u=re(),v=re();
if(u==v)continue;
Add(u,v);Add(v,u);
}
sort(dot+1,dot+1+n);
_f(i,1,n)rk[dot[i].id]=i,minnt[i]=dot[rk[i]].t;
_f(i,1,n)//按照s拓展
{
// chu("bfs:%d\n",dot[i].id);
BFS(dot[i].id,dot[i].s,dot[i].t);
if(hsv==n)break;
}
_f(i,1,n)chu("%d ",ans[i]);
return 0;
}
/*
s从大到小排序
如果此时所有点已经被更新到
break
输出答案
4 3
2 3 1
1 1 4
1 2 2
1 1 3
1 2
1 3
1 4
9 10
1 9 1
1 8 6
7 4 2
3 5 9
3 5 8
9 3 7
4 5 5
6 2 1
1 2 10
1 2
1 3
3 4
3 5
4 6
4 7
1 8
1 9
1 5
*/
正确:from wudi
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register int
#define pc_ putchar(' ')
#define pc_n putchar('\n')
#define Bessie int
inline int read()
{
int A = 0, FL = 1;
char CH = getchar();
while(CH < '0' || CH > '9') FL = CH == '-' ? -1 : 1, CH = getchar();
while(CH >= '0' && CH <= '9') A = (A << 3) + (A << 1) + (CH ^ '0'), CH = getchar();
return A * FL;
}
inline void ot(int x)
{
if(x < 0) putchar('-'), x = -x;
if(x >= 10) ot(x / 10);
putchar(x % 10 | '0');
}
const int CTR = 2e5 + 7;
int n, m;
struct my
{
int s, idx;
}b[CTR];
bool cmp(my x, my y)
{
return x.s > y.s;
}
struct city
{
int s, t, c;
}a[CTR];
struct edge
{
int to, nxt;
}e[CTR << 1];
int h[CTR], etot;
void addedge(int x, int y)
{
e[++etot].to = y;
e[etot].nxt = h[x];
h[x] = etot;
}
int ans[CTR];
int st;
int minnt[CTR];
void dfs(int x, int mint)
{
ans[x] = max(a[st].s, ans[x]);
// printf("x:%d ans:%d\n", x, ans[x]);
minnt[x] = max(minnt[x], mint);
for(re i = h[x], v; i; i = e[i].nxt)
{
v = e[i].to;
if((ans[v] < a[st].s || minnt[v] < mint) && a[v].c <= mint)
dfs(v, min(mint, a[v].t));
}
}
void work() // 现在让 st 作为贡献答案的终点
{
// printf("st:%d\n", st);
dfs(st, a[st].t);
}
Bessie main()
{
n = read(), m = read();
for(re i = 1; i <= n; ++i)
{
a[i].c = read(), a[i].t = read(), a[i].s = read();
b[i].s = a[i].s, b[i].idx = i;
}
sort(b + 1, b + n + 1, cmp);
for(re i = 1, x, y; i <= m; ++i)
{
x = read(), y = read();
addedge(x, y);
addedge(y, x);
}
for(re i = 1; i <= n; ++i)
{
st = b[i].idx;
work();
}
for(re i = 1; i <= n; ++i)
{
ot(ans[i]),pc_;
}
return 0;
}
浙公网安备 33010602011771号