解题思路: 本题研究一下数据就可以发现,可以无视矩形,只看平行于y轴的边一条边即可,于是我们可以把这个题目转换为,两条直线和若干条线段相交的问题。我们设直线为
y
=
a
,
y
=
b
y=a,y=b
y=a,y=b我们枚举
a
a
a ,
y
=
a
y=a
y=a 相交了多少条线段,可以通过差分直接求出。然后我们将a经过的线段全部删除,在剩下的数组中找到最大的与
y
=
b
y=b
y=b相交的线段数即可。这里我们倒叙枚举端点,使用线段树来维护寻找
y
=
b
y=b
y=b相交多少条线段的过程。
constint N =2e5+5;int n;int L[N], R[N], A[N], cnt;int c[N];
vector <int> ve[N];struct node {int tag, maxn;}tr[N <<2];void build (int i ,int l ,int r){
tr[i].maxn = tr[i].tag =0;if(l == r)return;int mid =(l + r)>>1;
build (i <<1, l , mid);
build (i <<1|1, mid +1, r);}void push_down (int i){if(tr[i].tag){
tr[i<<1].maxn += tr[i].tag;
tr[i<<1|1].maxn += tr[i].tag;
tr[i<<1].tag += tr[i].tag;
tr[i<<1|1].tag += tr[i].tag;
tr[i].tag =0;return;}}void update (int i ,int l ,int r,int L ,int R){if(L <= l && R >= r){
tr[i].maxn +=1;
tr[i].tag +=1;return;}push_down(i);int mid =(l + r)>>1;if(L <= mid) update (i<<1,l , mid, L, R);if(R > mid) update (i<<1|1, mid+1,r , L, R);
tr[i].maxn = max (tr[i<<1].maxn, tr[i<<1|1].maxn);}intmain(){
CLOSE;
cin >> n;for(int i =1; i <= n ; i ++){int x1, x2, y1, y2;
cin >> x2 >> y2 >> x1 >> y1;
L[i]= y1, R[i]= y2;
A[++ cnt]= y1;
A[++ cnt]= y2;}
sort (A +1, A +1+ cnt);int len = unique (A +1, A +1+ cnt)- A -1;for(int i =1; i <= n ; i ++){
L[i]=lower_bound(A +1, A +1+ len, L[i])- A;
R[i]=lower_bound(A +1, A +1+ len, R[i])- A;
ve[L[i]].pb (R[i]);}for(int i =1; i <= n ; i ++)
c[L[i]]+=1, c[R[i]+1]-=1;for(int i =1; i <= len ; i ++)
c[i]+= c[i-1];int ans =0;
build (1,1, len);for(int i = len ; i >=1; i --){
ans = max (ans, c[i]+ tr[1].maxn);for(auto j : ve[i]){update(1,1, len, i, j);}}
cout << ans << endl;}
D - Go Latin
解题思路: 模拟一下就行
int n;
string str;intmain(){
cin >> n;for(int i =1; i <= n ; i ++){
cin >> str;int len = str.length();if(str[len-1]=='a')
str +='s';elseif(str[len-1]=='i'|| str[len-1]=='y'){
str[len-1]='i';
str +="os";}elseif(str[len-1]=='l')
str +="es";elseif(str[len-1]=='n'||(str[len-1]=='e'&& str[len-2]=='n')){if(str[len-1]=='n')
str[len-1]='a', str +="nes";else
str[len-2]='a', str[len-1]='n', str +="es";}elseif(str[len-1]=='o')
str +='s';elseif(str[len-1]=='r')
str +="es";elseif(str[len-1]=='t')
str +="as";elseif(str[len-1]=='u')
str +="s";elseif(str[len-1]=='v')
str +="es";elseif(str[len-1]=='w')
str +="as";else
str +="us";
cout << str << endl;}}
constint N =2005;int n, m, w, h;int a[N], b[N], mark[N];int pre[N];int vis[N][N];struct node {int val,id;booloperator<(const node& no)const{return val < no.val;}};
p_queue <node> q;intmain(){
cin >> m >> n >> w >> h;for(int i =1; i <= m ; i ++)
pre[i]=-2005;for(int i =1; i <= m ; i ++)
cin >> a[i];for(int i =1; i <= n ; i ++)
cin >> b[i];int ok =1;for(int i =1; i <= n ; i ++){for(int j =1; j <= m ; j ++)if(a[j]>0&&!mark[j]&& i - pre[j]-1>= h)
q.push ({a[j],j}), mark[j]=1;int res = b[i];while(!q.empty()){if(res ==0)break;auto x = q.top();
q.pop();
mark[x.id]=0;
vis[x.id][i]=1;
pre[x.id]= i + w -1;
a[x.id]-= w;
res --;for(int j = i ; j <= i + w -1; j ++)
b[j]--;}if(res){
ok =0;break;}}if(!ok){
cout <<-1<< endl;return0;}
cout <<1<< endl;for(int i =1; i <= m ; i ++){for(int j =1; j <= n ; j ++)if(vis[i][j])
cout << j <<" ";
cout << endl;}}
constint N =4e5+5;int n , m;int head[N], cnt;struct node {int t, next;}edge[N <<1];void add (int f,int t){
edge[cnt].t = t;
edge[cnt].next = head[f];
head[f]= cnt ++;}int times , tot ;int dfn[N], low[N], vis[N], st[N], scc[N], type =0;void tarjan (int u){
dfn[u]= low[u]=++ times;
st[++ tot]= u;
vis[u]=1;for(int i = head[u]; i !=-1; i = edge[i].next){int v = edge[i].t;if(!dfn[v]){tarjan(v);
low[u]= min (low[u], low[v]);}elseif(vis[v])
low[u]= min (low[u], dfn[v]);}if(low[u]== dfn[u]){
type ++;do{
scc[st[tot]]= type;
vis[st[tot]]=0;
tot --;}while(u != st[tot +1]);}return;}int x[5], y[5];intmain(){
CLOSE;
mem (head,-1);
cin >> n >> m;for(int i =1; i <= m ; i ++){char op;for(int j =1; j <=3; j ++){
cin >> x[j]>> op;if(op =='B')
y[j]=1;else
y[j]=0;}
add (x[1]+(1- y[1])* n, x[2]+ n * y[2]);
add (x[1]+(1- y[1])* n, x[3]+ n * y[3]);
add (x[2]+(1- y[2])* n, x[1]+ n * y[1]);
add (x[2]+(1- y[2])* n, x[3]+ n * y[3]);
add (x[3]+(1- y[3])* n, x[1]+ n * y[1]);
add (x[3]+(1- y[3])* n, x[2]+ n * y[2]);}for(int i =1; i <=2* n ; i ++)if(!dfn[i])
tarjan (i);for(int i =1; i <= n ; i ++){if(scc[i]== scc[i + n]){
cout <<-1<< endl;return0;}}for(int i =1; i <= n ; i ++){if(scc[i]< scc[i + n])
cout <<'R';else
cout <<'B';}
cout << endl;return0;}