社区讨论
珂朵莉求调教
P13983数列分块入门 8参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mli3wxai
- 此快照首次捕获于
- 2026/02/11 22:10 上周
- 此快照最后确认于
- 2026/02/11 23:55 上周
样例过,但全T了,蒟蒻初学ODT,求调
CPP#include<bits/stdc++.h>
#define LoveCyrene ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;;
constexpr int N=3e5+7;
struct Zakino{
int left,right;
long long value;
int prevent,next;
}Node[N];
int head,tail,total,Free;
void InitList(int n){
Free=1;
for (int i=0;i<n-1;i++){
Node[i].next=i+1;
}
Node[n-1].next=0;
}
int NewNode(){
if(Free==0) return 0;
int ID=Free;
Free=Node[Free].next;
return ID;
}
void FreeNode(int ID){
Node[ID].next=Free;
Free=ID;
}
void InitNode(int ID,int Left,int Right,long long int Value){
Node[ID].left=Left;
Node[ID].right=Right;
Node[ID].value=Value;
Node[ID].prevent=Node[ID].next=0;
}
void lnsert(int Current,int Next){
if(Current==0){
if(head==0){
head=tail=Next;
Node[Next].prevent=Node[Next].next=0;
}
else{
Node[Next].next=head;
Node[head].prevent=Next;
Node[Next].prevent=0;
head=Next;
}
}
else{
int OldNext=Node[Current].next;
Node[Current].next=Next;
Node[Next].prevent=Current;
Node[Next].next=OldNext;
if(OldNext) Node[OldNext].prevent=Next;
else tail=Next;
}
}
void erase(int Current){
int prevent=Node[Current].prevent;
int next=Node[Current].next;
if(prevent) Node[prevent].next=next;
else head=next;
if(next) Node[next].prevent=prevent;
else tail=prevent;
Node[Current].prevent=Node[Current].next=0;
}
int FindNode(int pos){
int Current=head;
while(Current){
if(Node[Current].left<=pos&&Node[Current].right>=pos) return Current;
Current=Node[Current].next;
}
return 0;
}
int split(int pos){
if(pos<1) return head;
int Current=FindNode(pos);
if(Current==0) return tail;
if(Node[Current].left==pos) return Current;
int left=Node[Current].left;
int right=Node[Current].right;
long long int value=Node[Current].value;
Node[Current].right=pos-1;
int New=NewNode();
InitNode(New,pos,right,value);
lnsert(Current,New);
return New;
}
void assign(int Left,int Right,long long int Value){
if(Left>Right) return ;
int CurrenLeft=split(Left);
int CurrenRight=split(Right+1);
int Prevent=Node[CurrenLeft].prevent;
Node[CurrenLeft].left=Left;
Node[CurrenLeft].right=Right;
Node[CurrenLeft].value=Value;
int Current=Node[CurrenLeft].next;
while(Current!=CurrenRight&&Current){
int Next=Node[Current].next;
erase(Current);
FreeNode(Current);
Current=Next;
}
Node[CurrenLeft].next=CurrenRight;
if(CurrenRight)Node[CurrenRight].prevent=CurrenLeft;
else tail=CurrenLeft;
if(Prevent&&Node[Prevent].value==Value&&Node[Prevent].right+1==Left){
Node[Prevent].right=Right;
Node[Prevent].next=Node[CurrenLeft].next;
if(Node[CurrenLeft].next){
Node[Node[CurrenLeft].next].prevent=Prevent;
}
else tail=Prevent;
erase(CurrenLeft);
FreeNode(CurrenLeft);
}
}
long long int CountValue(int Left,int Right,int Value){
if(Left>Right) return 0;
int CurrenLeft=split(Left);
int CurrenRight=split(Right+1);
int Current=CurrenLeft;
long long int AnsW=0;
while(Current!=CurrenRight&&Current){
if(Node[Current].value==Value) AnsW+=Node[Current].right-Node[Current].left+1;
Current=Node[Current].next;
}
return AnsW;
}
void ODT(int n,long long int InitValue){
InitList(n);
int First=NewNode();
InitNode(First,1,n,InitValue);
head=tail=First;
}
int main(){
LoveCyrene;
int n;cin>>n;ODT(n,0);
for (int i=1;i<=n;i++){
int x;cin>>x;
assign(i,i,x);
}
while(n--){
int Left,Right,Value;
cin>>Left>>Right>>Value;
cout<<CountValue(Left,Right,Value)<<'\n';
assign(Left,Right,Value);
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...