Problem:
Problem C:
Online Quizu System
ICPC (Internet Contents Providing Company) is working on a killer game named Quiz Millionaire Attack.
It is a quiz system played over the Internet. You are joining ICPC as an engineer, and you are responsible
for designing a protocol between clients and the game server for this system. As bandwidth assigned for
the server is quite limited, data size exchanged between clients and the server should be reduced as much
as possible. In addition, all clients should be well synchronized during the quiz session for a simultaneous
play. In particular, much attention should be paid to the delay on receiving packets.
To verify that your protocol meets the above demands, you have decided to simulate the communication
between clients and the server and calculate the data size exchanged during one game.
A game has the following process. First, players participating and problems to be used are fixed. All
players are using the same client program and already have the problem statements downloaded, so you
don’t need to simulate this part. Then the game begins. The first problem is presented to the players,
and the players answer it within a fixed amount of time. After that, the second problem is presented,
and so forth. When all problems have been completed, the game ends. During each problem phase,
the players are notified of what other players have done. Before you submit your answer, you can know
who have already submitted their answers. After you have submitted your answer, you can know what
answers are submitted by other players.
When each problem phase starts, the server sends a
synchronization packet for problem-start
to all the
players, and begins a polling process. Every 1,000 milliseconds after the beginning of polling, the server
checks whether it received new answers from the players strictly before that moment, and if there are
any, sends a notification to all the players:
If a player hasn’t submitted an answer yet, the server sends it a
notification packet type A describing
  others’ answers
about the newly received answers.
If a player is one of those who submitted the newly received answers, the server sends it a
notification
  packet type B describing others’ answers
about all the answers submitted by other players (i.e.
  excluding the player him/herself’s answer) strictly before that moment.
If a player has already submitted an answer, the server sends it a
notification packet type B describing
  others’ answers
about the newly received answers.
Note that, in all above cases, notification packets (both types A and B) must contain information
  about at least one player, and otherwise a notification packet will not be sent.
When 20,000 milliseconds have passed after sending the
synchronization packet for problem-start
, the
server sends notification packets of type A or B if needed, and then sends a
synchronization packet for
problem-end
to all the players, to terminate the problem.
On the other hand, players will 
...(truncated)

Submitted solutions:

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_T = 20000;
const int INT_T = 1000;

const int MAX_M = 100;
const int MAX_N = 100;

const int PKT_HDR = 3;

/* typedef */

struct Answer {
  int p, t, size;
  Answer() {}
  Answer(int _p, int _t, int _size) { p = _p, t = _t, size = _size; }
  bool operator<(const Answer& a0) const { return t < a0.t; }
  void print() { printf("Answer:p=%d,t=%d,size=%d\n", p, t, size); }
};

typedef vector<Answer> va;

/* global variables */

int m, n, l;
int ds[MAX_M];
int ssent, srecv, csents[MAX_M], crecvs[MAX_M];
va vans;
int ansed[MAX_M], newansed[MAX_M];

/* subroutines */

/* main */

int main() {
  for (bool first = true;; first = false) {
    cin >> m >> n;
    if (m == 0) break;

    ssent = srecv = 0;
    memset(csents, 0, sizeof(csents));
    memset(crecvs, 0, sizeof(crecvs));

    for (int i = 0; i < m; i++)
      cin >> ds[i];

    while (n--) {
      vans.clear();
      
      cin >> l;
      for (int i = 0; i < l; i++) {
	int p, t;
	string ans;
	cin >> p >> t >> ans;
	vans.push_back(Answer(p, t + 2 * ds[p], ans.length()));
      }
      sort(vans.begin(), vans.end());

      // problem-start
      for (int i = 0; i < m; i++) {
	ssent += PKT_HDR;
	crecvs[i] += PKT_HDR;
      }

      int ai = 0;
      int nansed = 0, sum = 0;
      memset(ansed, 0, sizeof(ansed));
      
      for (int t = 0; t <= MAX_T; t += INT_T) {
	//printf("t=%d\n", t);
	int nnewansed = 0, newsum = 0;
	memset(newansed, 0, sizeof(newansed));

	// receive Answer
	while (ai < l && vans[ai].t < t) {
	  Answer& vai = vans[ai];
	  //vai.print();
	  
	  int data = 2 + vai.size;
	  csents[vai.p] += PKT_HDR + data;
	  srecv += PKT_HDR + data;
	  ansed[vai.p] = newansed[vai.p] = data;
	  nansed++;
	  nnewansed++;
	  sum += data;
	  newsum += data;
	  ai++;
	}

	// notification
	if (nnewansed > 0) {
	  for (int i = 0; i < m; i++) {
	    if (ansed[i] == 0) {	// type A
	      int pkt = PKT_HDR + 1 + nnewansed;
	      ssent += pkt;
	      crecvs[i] += pkt;
	      //printf("  t=%d: type A->%d, %d byte\n", t, i, pkt);
	    }
	    else if (newansed[i] > 0 && nansed > 1) {	// type B (exclude)
	      int pkt = PKT_HDR + 1 + sum - newansed[i];
	      ssent += pkt;
	      crecvs[i] += pkt;
	      //printf("  t=%d: type B(excl)->%d, %d byte\n", t, i, pkt);
	    }
	    else if (newansed[i] == 0 && ansed[i] > 0) {	// type B
	      int pkt = PKT_HDR + 1 + newsum;
	      ssent += pkt;
	      crecvs[i] += pkt;
	      //printf("  t=%d: type B->%d, %d byte\n", t, i, pkt);
	    }
	  }
	}
      }

      // problem-end
      for (int i = 0; i < m; i++) {
	ssent += PKT_HDR + 1;
	crecvs[i] += PKT_HDR + 1;
      }
    }

    if (! first) cout << endl;
    
    printf("%d %d\n", ssent, srecv);
    for (int i = 0; i < m; i++)
      printf("%d %d\n", csents[i], crecvs[i]);
  }

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1228
final_rank: 2

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;

struct Answer{
  int player;
  int time_sent;
  int time_rec;
  string answer;
};

int main()
{
  int n, m;
  bool first = true;
  while( cin >> n >> m && n && m ){
    int delay[n];
    int server_sent = 0;
    int server_rec  = 0;
    int sent[n];
    int rec[n];

    if( !first ){
      cout << endl;
    }else first = false;
    
    for(int i = 0; i < n; ++i){
      cin >> delay[i];
      sent[i] = 0;
      rec[i] = 0;
    }

    for(int prob = 0; prob < m; ++prob){
      int L;
      map<int,vector<Answer> > all_ans;

      // problem-start
      server_sent += 3*n;
      for(int i = 0; i < n; ++i){
        rec[i] += 3;
      }
      
      cin >> L;
      for(int i = 0; i < L; ++i){
        Answer ans;
        cin >> ans.player >> ans.time_sent >> ans.answer;
        //cout << ans.player << ' ' << ans.time_sent << ' ' << ans.answer << endl;
        ans.time_rec = ans.time_sent + 2*delay[ans.player];
        all_ans[ ans.time_rec ].push_back( ans );
        
        server_rec += 3+1+1+ans.answer.length();
        sent[ans.player] += 3+1+1+ans.answer.length();
      }

      int time = 1000;
      bool old_submit[n];
      bool new_submit[n];
      Answer submit_answer[n];
      vector<Answer> old_ans;
      vector<Answer> new_ans;
      
      for(int i = 0; i < n; ++i){
        old_submit[i] = false;
        new_submit[i] = false;
      }

      while(time <= 20000 ){
        //cout << "TIME : <" << time << endl;
        for(int i = 0; i < (int)new_ans.size(); ++i){
          old_ans.push_back( new_ans[i] );
        }
        for(int i = 0; i < n; ++i){
          //cout << sent[i] << ' ' << rec[i] << endl;
          if( new_submit[i] ){
            old_submit[i] = new_submit[i];
          }
        }
        //cout << endl;

        new_ans.clear();
        for(int i = 0; i < n; ++i){
          new_submit[i] = false;
        }
  
        //cout << endl;

        map<int,vector<Answer> >::iterator it = all_ans.lower_bound(time - 1000);
        for(;it!=all_ans.end()&&it->first<time;++it){
          // for newly recieved
          //cout << it->first <<endl;
          for(int i = 0; i < (int)it->second.size(); ++i){
            new_ans.push_back( it->second[i] );
            new_submit[ it->second[i].player ] = true;
            submit_answer[ it->second[i].player ] = it->second[i];
          }
        }


        for(int i = 0; i < n; ++i){
          //cout << old_submit[i]  << ' ' << new_submit[i] << endl;
        }
        
        
        for(int i = 0; i < n; ++i){
          if( !old_submit[i] && !new_submit[i] ){
            // not yet submitted
            int sent_b = 3+1+new_ans.size();
            if( new_ans.size() > 0 ){
              server_sent += sent_b;
              rec[i] += sent_b;
            }
            //cout << new_ans.size() << ' ' << "not yet " << i << ' ' << sent_b << endl;
          }
          else if( old_submit[i] && !new_submit[i] ){
            // submitted but not newly
            int sent_b = 3+1;
            int cnt=0;
            for(int j = 0; j < (int)new_ans.size(); ++j){
              ++cnt;
              sent_b += 1+1+new_ans[j].answer.length();
            }
            if( cnt > 0 ){
              server_sent += sent_b;
              rec[i] += sent_b;
            }
            //cout << cnt << " old submit " << i << ' ' << sent_b << endl;
          }
          else if( new_submit[i] ){
            // submitted newly
            int sent_b = 3+1;
            int cnt = 0;
            for(int j = 0; j < (int)new_ans.size(); ++j){
              if( new_ans[j].player != i ){
                ++cnt;
                sent_b += 1+1+new_ans[j].answer.length();
              }
            }
            for(int j = 0; j < (int)old_ans.size(); ++j){
              if( old_ans[j].player != i ){
                ++cnt;
                sent_b += 1+1+old_ans[j].answer.length();
              }
            }
            
            if( cnt > 0 ){
              server_sent += sent_b;
              rec[i] += sent_b;
            }
            //cout << cnt << " newly " << i << ' ' << sent_b << endl;
          }
        }
 
        time += 1000;
      }
      // problem-end
      server_sent += 4*n;
      for(int i = 0; i < n; ++i){
        rec[i] += 4;
      }
      
    }


    cout << server_sent << ' ' << server_rec << endl;
    for(int i = 0; i < n; ++i){
      cout << sent[i] << ' ' << rec[i] << endl;
    }

  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 952
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <cstring>
#include <queue>
using namespace std;

class Ans
{
public:
	int p,t,l;
	Ans(int p, int t, int l)
		:p(p),t(t),l(l)
	{}

	bool operator<(const Ans& ans) const
	{
		return t>ans.t;
	}
};

int M,N,D[100];
int ssend, srecv;
int psend[100], precv[100];

void calc(priority_queue<Ans>& q)
{
	int tt=1,ansn=0,ansl=0,alansn=0, alansl=0;
	bool ansed[100]={0},nwansed[100]={0};
	int lg[100]={0};
	
	q.push(Ans(0,99999,0));

	while(1)
	{
		Ans a=q.top(); 
		if(tt > 20) break;
		
		if(a.t < tt*1000) 
		{
			ansed[a.p]=1;
			nwansed[a.p]=1;
			
			ansn++;
			ansl+=a.l;
			alansn++;
			alansl+=a.l;
			
			lg[a.p]=a.l;
			
			q.pop();
		}
		else
		{
			++tt;
			if(ansn==0) continue;
			
			for(int i=0; i<M; i++)
			{
				if(nwansed[i])
				{
					if(alansn>1)
					{
						ssend+=4+2*(alansn-1)+(alansl-lg[i]);
						precv[i]+=4+2*(alansn-1)+(alansl-lg[i]);
					}
				}
				else if(ansed[i])
				{
					ssend+=4+2*ansn+ansl;
					precv[i]+=4+2*ansn+ansl;
				}
				else
				{
					ssend+=4+ansn;
					precv[i]+=4+ansn;
				}
				
			}
			
			ansn=0;
			ansl=0;
			memset(lg,0,sizeof(lg));
			memset(nwansed, 0, sizeof(nwansed));
		}
	}
}

int main()
{
	bool b=0;
	while(cin >> M >> N, (M||N))
	{
		if(b) cout << endl;
		b=1;
		
		for(int i=0; i<M; i++)
			cin >> D[i];

		ssend=0;
		srecv=0;
		memset(psend,0,sizeof(psend));
		memset(precv,0,sizeof(precv));

		for(int i=0; i<N; i++)
		{
			ssend+=3*M;
			for(int j=0; j<M; j++)
				precv[j]+=3;
			
			int L;
			cin >> L;
			priority_queue<Ans> q;
			for(int j=0; j<L; j++)
			{
				int P,T;
				string A;
				cin >> P >> T >> A;
				q.push(Ans(P,T+D[P]*2,A.size()));

				psend[P]+=5+A.size();
				srecv+=5+A.size();
			}

			calc(q);
			ssend+=4*M;
			for(int j=0; j<M; j++)
				precv[j]+=4;
			
		}

		cout << ssend << " " << srecv << endl;
		for(int i=0; i<M; i++)
			cout << psend[i] << " " << precv[i] << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 924
final_rank: 1