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 DescriptionWith 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 For convenience, record num(s) as 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:
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 The network administrator should regularly check the allocation of addresses. Specifically, there are two operations as follows:
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 formatRead 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 formatoutput 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 Sample input 1
样例输出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)。
|
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: