CCF-CSP Zhenti "202303-4 Interstellar Network II" ideas + python, c++ full score solution

Students who want to check the real questions and solutions of other questions can go to: CCF-CSP real questions with solutions


Question No.: 202303-4
Question name: Interstellar Network II
time limit: 2.0s
Memory limit: 1.0GB
Problem Description:

Problem Description

With the further construction and scale increase of the interstellar network, a new problem appeared in front of the network engineers—the address space was not enough! It turns out that the Interstellar Network adopts the traditional IPv6 protocol. Although there are 2128 available addresses, in the face of the vast universe and the explosive growth of network users, such a huge address space is also facing the day when it will be exhausted.

The research and development of the new communication protocol was handed over to the famous holy land of network technology - Sisi Aifer. Finally, after 2333 years of unremitting efforts, the engineers of Sissy Ivor star designed a new protocol - "Sissy Ivor IP Protocol", also known as IPxxaf.

In the IPxxaf protocol, an address consists of n bits, where n is a multiple of 16. When expressing an address in daily life, the hexadecimal notation similar to the IPv6 protocol is used, and every 4 digits are  : separated by . For example, when n=32, the address is  2a00:0001 , which means a binary  0010 1010 0000 0000 0000 0000 0000 0001 address.  Note that there will be no situation in which the leading part of each group is omitted  0 or  :: a section  is omitted in IPv6.0

For convenience, record num(s) as  s an n-bit binary number composed of high-order bits first and lower-order bits later, and a "continuous address" is a series of addresses in which num(s) forms a continuous range.

The network administrator of SISI is responsible for the allocation and management of addresses. Initially, the entire address space is unallocated. Users can request some addresses from the administrator at any time:

1 id l r: Indicates a continuous address block where the user id applies for an address within the range l∼r (including l and r, the same below).

In the address application operation, the administrator needs to check whether the address is available. If none of the addresses requested by the user have been allocated, the check will pass; if there are addresses already allocated to other users, the check will fail.

But there is a special case: there are no addresses that have been allocated to other users in the applied addresses, but some addresses that have been previously allocated to the user himself. At this point, it can be considered that the check is passed, but if all the addresses applied for have been previously assigned to the user, the check will fail.

If the above check is passed, the administrator returns to the user  YESand assigns the requested address to the user; if not, returns to the user  NOwithout changing the existing address assignment.

The network administrator should regularly check the allocation of addresses. Specifically, there are two operations as follows:

2 s: Check to which user address s is assigned. If not assigned, the result is 0.

3 l r: Check whether all addresses in the range l∼r are fully assigned to a user. If yes, answer the number of the user; if no, answer 0.

During the operation of the entire network, there have been q operations of applying for addresses and checking address allocation. As an important network technology consultant of Sisi Iversus, you have to help the network administrator process each operation in turn and answer the corresponding results.

input format

Read data from standard input.

In the first line, 2 positive integers n,q.

The following q lines, one operation per line, the format is as above, where id is a positive integer, l, r, s are all IPxxaf address strings, and the hexadecimal system is represented by numbers and lowercase letters.

output format

output to standard output.

Output q lines, each with a non-negative integer or string representing the result of this operation.

Among them, for operation 1, output  YES or  NO; for operation 2,3, output a non-negative integer.

Sample input 1

32 12
1 1 0001:8000 0001:ffff
2 0001:a000
3 0001:c000 0001:ffff
1 2 0000:0000 000f:ffff
2 0000:1000
1 1 0001:8000 0001:8fff
1 2 0000:0000 0000:ffff
2 0000:1000
1 1 0002:8000 0002:ffff
3 0001:8000 0002:ffff
1 1 0001:c000 0003:ffff
3 0001:8000 0002:ffff

样例输出1

YES
1
1
NO
0
NO
YES
2
YES
0
YES
1

样例解释

第 4 个操作时,由于用户 2 申请的部分地址已被分配给用户 1,因此申请不通过;

第 6 个操作时,由于用户 1 申请的全部地址已被分配给用户 1,因此申请不通过;

第 11 个操作时,用户 1 申请的部分地址已被分配给用户 1,其余地址尚未被分配,申请通过;

数据范围

对于所有数据,n≤512, q≤5×104,n 为 16 的倍数,id≤q,对于操作 1,3 保证 num(l)≤num(r)。

测试点编号 n≤ q≤ 特殊性质
1∼4 16 200
5∼6 64 200
7∼9 512 200
10∼11 16 20000
12∼13 64 50000
14∼16 512 50000 所有操作 1 的 id 互不相同
17∼20 512 50000

Source of real question: Interstellar Network II

 Interested students can code in this way for practice submission

Ideas explained:

        This question belongs to the classic question of line segment tree (discretization, single-point query, interval summation, interval maximum value). The line segment tree maintains the interval sum, which is used to record that several values ​​​​of the corresponding interval have been used, and the line segment tree maintains the maximum and minimum values, which is used to record which user id has been used. When the minimum value = maximum value, it means that it is used by exactly one user Pass. First, convert the maximum 32-dimensional number to decimal, compress it into an array of 32, and find the subscript mapping corresponding to each ip address after discretization and deduplication.

Operation 1: If [l, r] has not been used by the user, or [l, r] has only been used by the current user and is not full, it is feasible, otherwise it is not feasible; first check the sum of this interval in the line segment tree, Equal to 0 means that it has not been used, then it is feasible; otherwise, judge the maximum and minimum values ​​of the current interval, if the maximum and minimum values ​​are equal and the interval sum is less than the interval length, then it is feasible.

Operation 2: Single-point inquiry, check the maximum/minimum value of a single point to know which user has used it or not;

Operation 3: interval query, if [l, r] is used by only one user, then the interval sum is the interval length, and the maximum and minimum values ​​of the interval are equal. Note that when discretizing, the value of +1 to the right endpoint needs to be discretized into it , and consider the carry problem brought by +1, otherwise, it may appear that [1,2][4,5] are not adjacent before discretization, and become [1,2][3,4] phase after discretization Neighborhood situation;

 C++ full score solution:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15e4+10,M=5e4+10,K=170,B=32,INF=0x3f3f3f3f;
struct segtree{
	int n;
	struct node{int l,r,v,c,mn,mx;}e[N<<2];
	#define l(p) e[p].l
	#define r(p) e[p].r
	#define v(p) e[p].v
	#define c(p) e[p].c
	#define mn(p) e[p].mn
	#define mx(p) e[p].mx
	void up(int p){
		v(p)=v(p<<1)+v(p<<1|1);
		mn(p)=min(mn(p<<1),mn(p<<1|1));
		mx(p)=max(mx(p<<1),mx(p<<1|1));
	}
	void bld(int p,int l,int r){
		l(p)=l;r(p)=r;c(p)=0;
		if(l==r){v(p)=0;mn(p)=INF;mx(p)=-INF;return;}
		int mid=l+r>>1;
		bld(p<<1,l,mid);bld(p<<1|1,mid+1,r);
		up(p);
	}
	void psd(int p){
		if(c(p)){
			v(p<<1)=r(p<<1)-l(p<<1)+1;
			mn(p<<1)=min(mn(p<<1),c(p));
			mx(p<<1)=max(mx(p<<1),c(p));
			c(p<<1)=c(p);
			v(p<<1|1)=r(p<<1|1)-l(p<<1|1)+1;		
			mn(p<<1|1)=min(mn(p<<1|1),c(p));
			mx(p<<1|1)=max(mx(p<<1|1),c(p));
			c(p<<1|1)=c(p);
			c(p)=0; 
		}
	}
	void init(int _n){n=_n;bld(1,1,n);}
	void chg(int p,int ql,int qr,int v){
		if(ql>qr)return;
		if(ql<=l(p)&&r(p)<=qr){
			v(p)=r(p)-l(p)+1;
			mn(p)=min(mn(p),v);
			mx(p)=max(mx(p),v);
			c(p)=v;
			return;
		}
		psd(p);
		int mid=l(p)+r(p)>>1;
		if(ql<=mid)chg(p<<1,ql,qr,v);
		if(qr>mid)chg(p<<1|1,ql,qr,v);
		up(p);
	}
	int cnt(int p,int ql,int qr){
		if(ql<=l(p)&&r(p)<=qr)return v(p);
		int mid=l(p)+r(p)>>1,res=0;
		psd(p);
		if(ql<=mid)res+=cnt(p<<1,ql,qr);
		if(qr>mid)res+=cnt(p<<1|1,ql,qr);
		return res;
	}
	int amn(int p,int ql,int qr){
		if(ql<=l(p)&&r(p)<=qr)return mn(p);
		int mid=l(p)+r(p)>>1,res=INF;
		psd(p);
		if(ql<=mid)res=min(res,amn(p<<1,ql,qr));
		if(qr>mid)res=min(res,amn(p<<1|1,ql,qr));
		return res;
	}
	int amx(int p,int ql,int qr){
		if(ql<=l(p)&&r(p)<=qr)return mx(p);
		int mid=l(p)+r(p)>>1,res=-INF;
		psd(p);
		if(ql<=mid)res=max(res,amx(p<<1,ql,qr));
		if(qr>mid)res=max(res,amx(p<<1|1,ql,qr));
		return res;
	}
}seg;
int n,m,q,op,c;
array<int,B>f[N];
auto cal(string s){
	int d=0;
	array<int,B>ans={0};
	for(auto &y:s){
		if(y==':'){
			d++;
			continue;
		}
		int &v=ans[d];
		if('a'<=y && y<='f')v=v*16+(y-'a')+10;
		else v=v*16+(y-'0');
	}
	return ans;
}
auto add_one(array<int,B>y){
	y[n/16-1]++;
	for(int i=B-1;i;--i){
		if(y[i]>=65536){
			y[i]-=65536;
			y[i-1]++;
		}
	}
	return y;
}
int g(array<int,B>v){
	int x=lower_bound(f,f+c,v)-f;
	return x+1;
}
struct ask{
	int op,x;
	string s,t;
	void rd(){
		cin>>op;
		if(op==1)cin>>x;
		cin>>s;
		f[c++]=cal(s);
		if(op==2)t=s;
		else{
			cin>>t;
			f[c++]=cal(t);
			f[c]=add_one(f[c-1]);
			c++;
		}
	}
	void sol(){
		int l=g(cal(s)),r=g(cal(t)),w=seg.cnt(1,l,r);
		int mn=seg.amn(1,l,r),mx=seg.amx(1,l,r);
		if(op==1){
			if(!w || (w<r-l+1 && mn==mx && mn==x)){
				seg.chg(1,l,r,x);
				cout<<"YES"<<endl;
			}
			else{
				cout<<"NO"<<endl;
			}
		}
		else if(op==2){
			cout<<(mn==INF?0:mn)<<endl;
		}
		else{
			cout<<(w==r-l+1 && mn==mx?mn:0)<<endl;
		}
	}
}e[M];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=q;++i){
		e[i].rd();
	}
	sort(f,f+c);
	c=unique(f,f+c)-f;
	seg.init(c+5);
	for(int i=1;i<=q;++i){
		e[i].sol();
	}
	return 0;
}

 operation result:

Guess you like

Origin blog.csdn.net/weixin_53919192/article/details/131566208