社区讨论

珂朵莉求调教

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 条回复,欢迎继续交流。

正在加载回复...