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;
}
posted on 2022-10-12 18:58  HZOI-曹蓉  阅读(36)  评论(2)    收藏  举报