统计时间,采用栈实现.对于每一个login,直接入栈;对于logout,将栈中的对于项弹出,注意要弹出的项不一定在栈顶,这就要用一个辅助栈,将弹出项上的各项先弹出,在弹出目标后,再将他们压入栈中,同时对于弹出项用其起始时间和结束时间与当前记录中的起止时间比较,保留最长的时间段.
最后查询时,根据要求的时间区间,对于要查询的人,依次检查其记录中的每一项,累计总时间即可.
Source:
#include<iostream>
#include<stack>
using namespace std;
struct Node {
int in, out;
struct Node *next;
};
struct Data {
int t, nc, s;
};
stack<Data> current[10010];
Node da[10010];
Node* record[10010];
int main() {
int t, ls, le, i, n, m, r, q, ms, te, ts;
Node *temp, *p;
while (1) {
cin>>n>>m;
if (n==0&& m==0)
break;
for (i=1; i<=m; ++i) {
record[i]=NULL;
da[i].in=2000;
da[i].out=0;
}
cin>>r;
for (; r>0; --r) {
Data d, te;
cin>>d.t>>d.nc>>ms>>d.s;
if (d.s==0) {
stack<Data> he;
do {
te=current[ms].top();
current[ms].pop();
if (te.nc==d.nc) {
if(te.t<da[ms].in)da[ms].in=te.t;
if(d.t>da[ms].out)da[ms].out=d.t;
if (current[ms].empty() && he.empty()) {
temp=new Node();
temp->in=da[ms].in;
temp->out=da[ms].out;
temp->next=record[ms];
record[ms]=temp;
da[ms].in=2000;
da[ms].out=0;
}
break;
} else {
he.push(te);
}
} while (1);
while (!he.empty()) {
current[ms].push(he.top());
he.pop();
}
} else {
current[ms].push(d);
}
}
// for (i=1; i<=m; ++i) {
// cout<<i<<":";
// for (p=record[i]; p!=NULL; p=p->next)
// cout<<"["<<p->in<<","<<p->out<<"], ";
// cout<<endl;
// }
for (cin>>q; q>0; --q) {
cin>>ts>>te>>ms;
for (p=record[ms], t=0; p!=NULL; p=p->next) {
if (p->in <= ts)
ls=ts;
else
ls=p->in;
if (p->out >= te)
le=te;
else
le=p->out;
if (le>ls) {
t+=(le-ls);
// cout<<le-ls<<endl;
}
}
cout<<t<<endl;
}
}
return 0;
}