Example #1
0
	bool queryRange(int left, int right) {
		auto it = rc.lower_bound(make_pair(left, right));
		return it!=rc.end() && it->first <= left && it->second >= right;
	}
Example #2
0
int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
	int n;
	scanf("%d",&n);
	for (int i = 1; i <= n; ++i)
	{
		cir[i].read();
		son[i].clear();
	}
	son[0].clear();
	
	sort(cir+1,cir+n+1);
	e.clear();
	for( int i = 1; i <= n; ++i)
	{
		e.push_back(make_pair(cir[i].left,i));
		e.push_back(make_pair(cir[i].x + cir[i].r, -i));
	}
	sort(e.begin(),e.end());
	s.clear();
	for (int i = 0; i < e.size(); ++i)
	{
		cur = e[i].first;
		if (e[i].second > 0){
			int id = e[i].second;
			set<circmp>::iterator t = s.lower_bound(circmp(id));
			if(t == s.end())
			{
				fa[id] = 0;
				//son[0].push_back(id);
			}else{				
				int nid = (*t).id;
				if (cir[nid].contain(cir[id])){
					fa[id] = nid;
				//	son[id].clear();
					son[nid].push_back(id);
				}else{
					fa[id] = fa[nid];
				//	son[id].clear();
					son[fa[id]].push_back(id);
				}
			}
			s.insert(circmp(id));
			s.insert(circmp(-id));			
		}else{
			int id = -e[i].second;
			s.erase(circmp(id));
			s.erase(circmp(-id));
		}
	}
//	memset(maxx,-1,sizeof(maxx));
	
//	dfs(0);
	
		int ans = 0;
		for (int i = 1; i <= n; ++i) {
			if (fa[i] == 0) {
				ans ^= sg(i);
			}
		}
		puts(ans ? "Alice" : "Bob");
	
}
	
	return 0;
}
Example #3
0
bool track( std::map< unsigned long long, std::map<int,cv::Point2d> >* p_result, std::map<unsigned long long, std::multimap<int,cv::Point2d> >* p_ext_result, const Mat& occupancy, unsigned long long time_stamp )
{
    static TIME_MICRO_SEC timeTracking; // $BDI@W;~9o(B[usec]
                                 // [timeTracking - commonParam.termTracking, timeTrackig) $B$NHO0O$GDI@W=hM}$r9T$&;v$r0UL#$9$k(B

    static SamplerPosXYTVID sampler; // $BFCD'NL%5%s%W%i(B

    // storageLUM
    // 時刻tk(キー)に対応するLUM集合へのマップ
    // 時刻tkに対応する等速直線運動集合とは、[tk - extractlumParam.term, tk)のPEPMapから作成した等速直線運動集合のことである。
    static LUMStorage storageLUM;

    // tableLUMSlice
    // LUMスライステーブル
    // 時刻tk(キー)におけるLUMスライスの配列へのマップ
    static LUMSliceTable tableLUMSlice;

    // storageTrajectory
    // 作成中の軌跡要素
    static vector<TrajectoryElement> storageTrajectoryElement;

    // resultTrajectory
    // 追跡結果(IDと軌跡のマップ)
    static map<int,CTrajectory> resultTrajectory;

    //static vector<CTrajectory> prevTrajectoriesClustered;
    static map<unsigned long long, std::multimap<int,cv::Point2d> >  remainedExtendedResult;

    // idNext
    // 追跡結果(IDと軌跡のマップ)
    static int idNext;

    static TIME_MICRO_SEC timeEarliestPEPMap;

    static bool flgTrackingStarts;

    static set<TIME_MICRO_SEC> time_of_received_pepmap;

    bool ret = false;

    if( flgFirst ) {
        sampler.clear();
        storageLUM.clear();
        tableLUMSlice.clear();
        storageTrajectoryElement.clear();
        resultTrajectory.clear();
        remainedExtendedResult.clear();
        idNext = 1;
        timeEarliestPEPMap = time_stamp;
        timeTracking = timeEarliestPEPMap + commonParam.termTracking;
        //timeTracking = commonParam.termTracking + 1000000000; // debug code
        flgFirst = false;
        flgTrackingStarts = true;
        logTracking.init( "tracking.log" );
        viewer.SetStartTime( timeEarliestPEPMap );
    }

    // debug code
    //time_stamp = time_stamp - timeEarliestPEPMap + 1000000000;

    if( flgTrackingStarts ) {
        logTracking.set_tracking_block( timeTracking - commonParam.termTracking, timeTracking );
        logTracking.start();
        viewer.SetTrackingStatus( 0 );
        viewer.SetTrackingBlock( timeTracking - commonParam.termTracking, timeTracking );
        flgTrackingStarts = false;
    }
    
    time_of_received_pepmap.insert( time_stamp );

    logTracking.making_trajectory( TrackingProcessLogger::Start );

    // PEPMapをサンプラに追加する
    AddPEPMapToSampler( occupancy
                      , time_stamp
                        , &sampler
                        , extractlumParam.minPEPMapValue
                        , extractlumParam.maxPEPMapValue );

    //
    // LUM抽出
    vector<TIME_MICRO_SEC> addedTime;
    for( TIME_MICRO_SEC tk = timeTracking - commonParam.termTracking; tk <= time_stamp; tk += extractlumParam.interval ) {
        if( storageLUM.find( tk ) == storageLUM.end() ) {
            // 時刻tkのLUMを抽出
            ExtractLUM( &sampler
                        , tk
                        , &storageLUM[ tk ]
                        , &commonParam
                        , &extractlumParam
                        , true );
            addedTime.push_back( tk );

        }
    }

    //
    //  LUMスライステーブル作成
    if( !storageLUM.empty() ) {
        TIME_MICRO_SEC timeLatestLUM = storageLUM.rbegin()->first;
        addedTime.clear();
        // timeLatestLUMまでのLUMが得られているとき,LUMスライステーブルが作成できるのは
        // (timeLatestLUM - extractlumParam.term)まで。この範囲でLUMスライステーブルを作成する。
        for( TIME_MICRO_SEC tk = timeTracking - commonParam.termTracking
            ; tk <= timeLatestLUM - extractlumParam.term
            ; tk += commonParam.intervalTrajectory ) {
            if( tableLUMSlice.find( tk ) == tableLUMSlice.end() ) {
                // 時刻tkのLUMスライス作成
                //cerr << "LUMスライス追加: ";
                MakeLUMSlice( tk, &storageLUM, &tableLUMSlice[ tk ], &extractlumParam );
                addedTime.push_back( tk );
            }
        }
    }

    // tableLUMSliceに追加された各時刻に始点を定める。
    set<PosXYT,PosXYT_XYT_Less> originPos;
    const double intersticeOrigin = 1.0 / sqrt( mktrajectoryParam.densityOrigin ); // $B50@W$N;OE@F1;N$N4V3V(B
    const double rangeOrigin = mktrajectoryParam.distanceImpact * 2.0; // $B50@W$N>pJs(BX,Y$B:BI8$N<~$j(BrangeOrigin$B;MJ}$NHO0O$K;OE@$N8uJd$r:n@.$9$k(B
    int nOrigin = 0;
    for( vector<TIME_MICRO_SEC>::iterator iTk = addedTime.begin(); iTk != addedTime.end(); ++iTk ) {
        TIME_MICRO_SEC tk = *iTk;
        vector<LUMSlice>::iterator itLUMSlice = tableLUMSlice[ tk ].begin();
        for( ; itLUMSlice != tableLUMSlice[ tk ].end(); ++itLUMSlice ) {
            for( double px = itLUMSlice->pos.x - rangeOrigin / 2.0; px < itLUMSlice->pos.x + rangeOrigin / 2.; px += intersticeOrigin ) {
                for( double py = itLUMSlice->pos.y - rangeOrigin / 2.0; py < itLUMSlice->pos.y + rangeOrigin / 2.0; py += intersticeOrigin ) {
                    originPos.insert( PosXYT( (int)( px / intersticeOrigin ) * intersticeOrigin
                                                , (int)( py / intersticeOrigin ) * intersticeOrigin
                                                , tk ) );
                }
            }
        }
        nOrigin = originPos.size();
    }

    // MPIにより始点を各プロセスに割り振る
    // 以下,仮記述
    vector<PosXYT> originPosPerProcess;
    originPosPerProcess.assign( originPos.begin(), originPos.end() );

    //
    // 受け取った始点を基に新たな軌跡を生成する
    int nNewTrj = 0;
    vector<PosXYT>::iterator itOrigin = originPosPerProcess.begin();
    for( int i = 0; itOrigin != originPosPerProcess.end(); ++itOrigin, ++i ) {
        TrajectoryElement trjElement;
        trjElement.insert( *itOrigin );
        storageTrajectoryElement.push_back( trjElement );
        ++nNewTrj;
    }

    //
    // tableLUMSliceに追加された各時刻について軌跡を延長する
    for( vector<TIME_MICRO_SEC>::iterator iTk = addedTime.begin(); iTk != addedTime.end(); ++iTk ) {
        TIME_MICRO_SEC tk = *iTk;
        if( tableLUMSlice.begin()->first != tk ) {
            ExtendTrajectories( tk - commonParam.intervalTrajectory
                                , tk
                                , &storageTrajectoryElement
                                , &tableLUMSlice[ tk - commonParam.intervalTrajectory ]
                                , &commonParam
                                , &mktrajectoryParam );
        }
    }

    logTracking.making_trajectory( TrackingProcessLogger::End );

    if( !tableLUMSlice.empty() && tableLUMSlice.rbegin()->first >= timeTracking ) {
        cout << "Done with making trajectories." << endl;

        if( flgOutputTrackingProcessData2Files ) {
            // Output process infomation of making trajectories.
            double sumValue = std::accumulate( sampler.begin(), sampler.end(), 0.0, PosXYTV_Sum() );
            unsigned int nSample = (unsigned int)( plotParam.kSample /*3.0e-2*//*1.04e-4*/ * sumValue );
            OutputProcess( timeTracking - commonParam.termTracking//tableLUMSlice.begin()->first
                            , timeTracking//tableLUMSlice.rbegin()->first
                            , timeEarliestPEPMap
                            , &sampler
                            , nSample
                            , &storageTrajectoryElement
                            , NULL//pipeGnuplot_Trajectory
                            , extractlumParam.stDeviation
                            , &plotParam );
            cerr << "完了(nSample=" << nSample << ")" << endl;

            // debug code
            if( nSample <= 3 ) {
                cerr << "nSample is no more than 3." << endl;
            }
        }

        //
        // Clustering the trajectories
        //
        logTracking.clustering( TrackingProcessLogger::Start );
        viewer.SetTrackingStatus( 1 );

        cerr << "Calculating a distance table..." << endl;

        //
        // クラスタリングに用いる軌跡(長さがclusterigParam.minLength以上)を取り出す
        vector<TrajectoryElement> trajectoryElementOfMyProc;
        vector<TrajectoryElement>::iterator it = storageTrajectoryElement.begin();
        for( ; it != storageTrajectoryElement.end(); ++it ) {
            if( it->rbegin()->t - it->begin()->t >= clusteringParam.minLength ) {
                trajectoryElementOfMyProc.push_back( *it );
            }
        }

        size_t nAllTrj; // 総軌跡数
        nAllTrj = trajectoryElementOfMyProc.size();
        map<int,CTrajectory> trajectoryForClustering;
        int iTrj = 0;
        for( vector<TrajectoryElement>::iterator it = trajectoryElementOfMyProc.begin(); it != trajectoryElementOfMyProc.end(); ++it ) {
            trajectoryForClustering[ iTrj ].push_back( *it );
            //(*pRecv)[ iTrj ].push_back( *it );
            ++iTrj;
        }


        // 距離テーブルの初期化
        double* distTable = new double[ nAllTrj * nAllTrj ];
        for( size_t i = 0; i < nAllTrj * nAllTrj; ++i ) {
            distTable[ i ] = -2.0;
        }
        CTrajectory_Distance distanceTrajectory( clusteringParam.distanceLimit, clusteringParam.nLimit, clusteringParam.minCommonTimeRange );
        vector<size_t> iTrjToCol( nAllTrj ); // 各プロセスの距離テーブルにおいて列番号と軌跡番号の対応を示したもの
        for( size_t i = 0; i < nAllTrj; ++i ) {
            iTrjToCol[ i ] = i;
        }
        CalculateDistanceTable( distTable
                              , &iTrjToCol
                              , nAllTrj
                              , trajectoryForClustering.begin()
                              , trajectoryForClustering.end()
                              , &trajectoryForClustering
                              , distanceTrajectory );


        // クラスタリング
        vector<CTrajectory> trajectoriesClustered;

        // 初期クラスタの情報を,受信した軌跡一つずつから成るクラスタが生成されるよう準備する。
        vector< vector<int> > indexCluster;
        vector<int> classID( nAllTrj, -1 );
        for( int i = 0; i < (int)nAllTrj; ++i ) {
            indexCluster.push_back( vector<int>( 1, i ) );
        }

        double* dist;

        size_t nCluster;// = indexCluster.size();
        size_t prevNumOfCluster;// = nCluster;
        int cnt_loop = 0;
        do {
            vector< vector<int> > tmpIndexCluster;
            trajectoriesClustered.clear();
            for( vector< vector<int> >::iterator itCluster = indexCluster.begin(); itCluster != indexCluster.end(); ++itCluster ) {
                CTrajectory trj;
                for( vector<int>::iterator itIdxTrj = itCluster->begin(); itIdxTrj != itCluster->end(); ++itIdxTrj ) {
                    map<int,CTrajectory>::iterator itTrj;
                    if( ( itTrj = trajectoryForClustering.find( *itIdxTrj ) ) != trajectoryForClustering.end() ) {
                        trj.insert( trj.end(), itTrj->second.begin(), itTrj->second.end() );
                    } else {
                        cerr << "Trajectory no." << *itIdxTrj << " Not Found(" << nAllTrj << ")." << endl;
                        //exit( 1 );
                    }
                }
                if( !trj.empty() && VerifyClusteredTrajectories( trj, clusteringParam.distVerifyCluster ) ) {
                    trajectoriesClustered.push_back( trj );
                    tmpIndexCluster.push_back( *itCluster );
                }
            }

            // 距離テーブル配置
            nCluster = trajectoriesClustered.size();
            dist = new double[ nCluster * nCluster ];

            //cerr << "再クラスタリング(現在のクラスタ:" << nCluster << "[$B8D(B], $BMxMQ50@W!'(B" << usetrj.size() << "[$BK\(B]$B!K(B...";
            cerr << cnt_loop << "回目...";

            vector<CTrajectory> tmpTrajectoriesClustered( trajectoriesClustered.size() );
            vector<CTrajectory>::iterator itTmpTrj = tmpTrajectoriesClustered.begin();
            for( vector<CTrajectory>::iterator itTrj = trajectoriesClustered.begin(); itTrj != trajectoriesClustered.end(); ++itTrj, ++itTmpTrj ) {
                itTrj->Integrate( &(*itTmpTrj) );
                //cerr << "itTrj->front().size():" << itTrj->front().size() << ", itTmpTrj->front().size():" << itTmpTrj->front().size() << endl;
                //if( itTmpTrj->front().size() == 0 ) {
                //    exit( 1 );
                //}
            }

            for( size_t idx1 = 0; idx1 < tmpTrajectoriesClustered.size(); ++idx1 ) {
                for( size_t idx2 = idx1; idx2 < tmpTrajectoriesClustered.size(); ++idx2 ) {
                    size_t index1 = idx1 * nCluster + idx2;
                    size_t index2 = idx2 * nCluster + idx1;
                    //cerr << "nCluster = " << nCluster << endl;
                    //cerr << "idx1 = " << idx1 << ", $BMWAG?t(B = " << tmpTrajectoriesClustered[ idx1 ].size() << endl;
                    //cerr << "idx2 = " << idx2 << ", $BMWAG?t(B = " << tmpTrajectoriesClustered[ idx2 ].size() << endl;
                    if( false/*cnt_loop == 0*/ ) {
                        // $B:G=i$N%/%i%9%?%j%s%0$N$H$-$O@h$K5a$a$?5wN%%F!<%V%k$r;HMQ$9$k!#(B
                        dist[ index1 ] = dist[ index2 ] = distTable[ idx1 * nAllTrj + idx2 ];
                    } else {
                        dist[ index1 ] = dist[ index2 ] = distanceTrajectory( tmpTrajectoriesClustered[ idx1 ]
                                                                            , tmpTrajectoriesClustered[ idx2 ] );
                    }
                    //TrajectoryElement_Distance distanceTrajectoryElement( clusteringParam.distanceLimit, clusteringParam.nLimit, clusteringParam.minCommonTimeRange );
                    //cerr << "idx1:" << tmpTrajectoriesClustered[ idx1 ].front().size() << ", idx2:" << tmpTrajectoriesClustered[ idx2 ].front().size() << ", ";
                    //cerr << "$B5wN%(B = ";
                    //dist[ index1 ] = dist[ index2 ] = distanceTrajectoryElement( tmpTrajectoriesClustered[ idx1 ].front()
                    //                                                           , tmpTrajectoriesClustered[ idx2 ].front() );
                    //cerr << dist[ index1 ] << endl;
                }
            }

#if 1

            // クラスタを間引く
            cerr << "利用クラスタの選定...";
            vector<int> idxClusterUse;
            if( !tmpTrajectoriesClustered.empty() ) {
                vector<double> frequency( tmpTrajectoriesClustered.size(), 0.0 );
                CalcFrequency( (double*)&(frequency[ 0 ]), dist, tmpTrajectoriesClustered.size(), 0.1, clusteringParam.thDistance );
                ReduceTrajectory( &idxClusterUse, (double*)&(frequency[0]), frequency.size(), 55.0/*80.0*/ );
            }
            cerr << "完了(" << idxClusterUse.size() << "[個])...";

            // 距離テーブル再配置
            double* dist2 = new double[ idxClusterUse.size() * idxClusterUse.size() ];
            for( vector<int>::iterator itIdxCluster = idxClusterUse.begin(); itIdxCluster != idxClusterUse.end(); ++itIdxCluster ) {
                for( vector<int>::iterator it = idxClusterUse.begin(); it != idxClusterUse.end(); ++it ) {
                    size_t idxDst = distance( idxClusterUse.begin(), itIdxCluster ) * idxClusterUse.size()
                                    + distance( idxClusterUse.begin(), it );
                    size_t idxSrc = *itIdxCluster * nCluster + *it;
                    dist2[ idxDst ] = dist[ idxSrc ];
                }
            }

            vector<int> classID( idxClusterUse.size(), -1 );
            Clustering( &classID, dist2, idxClusterUse.size(), clusteringParam.distVerifyCluster );

            vector< vector<int> > tmp;
            Clustering2( &tmp, classID, dist2, idxClusterUse.size(), clusteringParam.thConnect, clusteringParam.thDistance );

            delete [] dist2;


            indexCluster.clear();
            for( vector< vector<int> >::iterator itClusterIdx = tmp.begin(); itClusterIdx != tmp.end(); ++itClusterIdx ) {
                vector<int> clusterIdx;
                for( vector<int>::iterator it = itClusterIdx->begin(); it != itClusterIdx->end(); ++it ) {
                    clusterIdx.insert( clusterIdx.end()
                                        , tmpIndexCluster[ idxClusterUse[ *it ] ].begin()
                                        , tmpIndexCluster[ idxClusterUse[ *it ] ].end() );
                }
                sort( clusterIdx.begin(), clusterIdx.end() );
                clusterIdx.erase( unique( clusterIdx.begin(), clusterIdx.end() ), clusterIdx.end() );
                indexCluster.push_back( clusterIdx );
            }

            prevNumOfCluster = nCluster;//idxClusterUse.size();// nCluster;
            nCluster = indexCluster.size();
            cerr << "終了(クラスタ:" << nCluster << "[個], trajectoriesClustered.size()=" << trajectoriesClustered.size() << ")";
            cerr << endl;

            //
            // Output process information of clustering
            if( flgOutputTrackingProcessData2Files ) {
                ++cnt_loop;
                if( trajectoriesClustered.size() < 30 ) {
                    ostringstream oss;
                    oss << cnt_loop;
                    double sumValue = accumulate( sampler.begin(), sampler.end(), 0.0, PosXYTV_Sum() );
                    unsigned int nSample = (unsigned int)( plotParam.kSample /*3.0e-2*//*1.04e-4*/ * sumValue );
                    OutputProcess( timeTracking - commonParam.termTracking//tableLUMSlice.begin()->first
                                    , timeTracking//tableLUMSlice.rbegin()->first
                                    , timeEarliestPEPMap
                                    , &sampler
                                    , nSample
                                    , &trajectoriesClustered
#ifdef WINDOWS_OS
			            , "C:\\Users\\fukushi\\Documents\\project\\HumanTracking\\bin\\tmp_trajectories\\"
#endif
#ifdef LINUX_OS
			            , "/home/kumalab/project/HumanTracking/bin/tmp_trajectories/"
#endif
                                    , oss.str()
                                    , NULL
                                    , &plotParam );
                }
                
            }
#endif
            delete [] dist;
        } while( prevNumOfCluster != nCluster );

        logTracking.clustering( TrackingProcessLogger::End );

        logTracking.renovation( TrackingProcessLogger::Start );
        viewer.SetTrackingStatus( 2 );

        //
        // Renovate the trajectories
        TrajectoriesInfo infoTrj;
        infoTrj.section.resize( 1 );

        cerr << "Started renovation: [ " << timeTracking - commonParam.termTracking - timeEarliestPEPMap
                << ", " <<  timeTracking - timeEarliestPEPMap << " )" << endl;

        // クラスタリングした軌跡を平均してinfoTrjに格納する
        infoTrj.trjElement.resize( trajectoriesClustered.size() );
        for( int i = 0; i < (int)trajectoriesClustered.size(); ++i ) {
            CTrajectory trj;
            trajectoriesClustered[ i ].Integrate( &trj );
            infoTrj.trjElement[ i ] = trj.front();
        }

//        if( myRank == 0 ) {
//            cout << " クラスタリングした軌跡を追加: 総計" << infoTrj.trjElement.size() << "[個]" << endl;
//        }

        // 前回の追跡結果(resultTrajectory)を[ timeTracking - commonParam.termTracking, timeTracking )で
        // クリップしてinfoTrjに格納する
        int idx = (int)trajectoriesClustered.size();
        map<int,int> reserve; // 軌跡番号と既存のIDの組み合わせ
        for( map<int,CTrajectory>::iterator itResult = resultTrajectory.begin(); itResult != resultTrajectory.end(); ++itResult ) {
            CTrajectory trj;
            trj = itResult->second;
            trj.Clip( timeTracking - commonParam.termTracking, timeTracking );
            if( !trj.empty() ) {
                infoTrj.trjElement.push_back( trj.front() );
                reserve[ idx ] = itResult->first;
                ++idx;
            }
        }

//        if( myRank == 0 ) {
//            cout << " 前回の追跡結果を追加: 総計" << infoTrj.trjElement.size() << "[個]" << endl;
//        }

        //
        // 軌跡の出力
//            if( myRank == 0 ) {
//                vector<CTrajectory> vectrj;
//                for( vector<TrajectoryElement>::iterator it = infoTrj.trjElement.begin(); it != infoTrj.trjElement.end(); ++it ) {
//                    CTrajectory trj;
//                    trj.push_back( *it );
//                    vectrj.push_back( trj );
//                }
//                double sumValue = accumulate( sampler.begin(), sampler.end(), 0.0, PosXYTV_Sum() );
//                unsigned int nSample = (unsigned int)( 1.04e-4 * sumValue );
//                OutputProcess( timeTracking - commonParam.termTracking//tableLUMSlice.begin()->first
//                             , timeTracking//tableLUMSlice.rbegin()->first
//                             , timeEarliestPEPMap
//                             , &sampler
//                             , nSample
//                             , &vectrj
//                             , "./tmp_preoptimize/"
//                             , ""
//                             , NULL
//                             , &plotParam );
//            }

        // セクション分割
        map<int,int> pointIdxToTrjNo;
        DivideIntoSections( &infoTrj, &pointIdxToTrjNo, rnvtrjParam );

        // 各セクションでセットを作成
        for( int i = 0; i < (int)infoTrj.section.size(); ++i ) {
            MakeSet( i, &infoTrj, &reserve );
//            cout << "  セクション" << i << ": " << infoTrj.section[ i ].trjSet.size() << "[個]" << endl;
        }

//        start_d = MPI_Wtime();
//        cout << "Optimize()...";
        // 最適解の探索
        vector<TrajectoryElement> opt;
        vector<int> idOpt;
        double min = -1.0;
        //if( myRank == 0 ) {
        cerr << "  Optimum analysis: # of sections" << (int)infoTrj.section.size() << endl;
        //}
        for( int idxSec = 0; idxSec < (int)infoTrj.section.size(); ++idxSec ) {
            min = -1.0;
            int idxMinSet = -1;
            vector<TrajectoryElement> optOfSec;
            vector<int> idOptOfSec;
            for( int idxSet = 0; idxSet < (int)infoTrj.section[ idxSec ].trjSet.size(); ++idxSet ) {
                vector<TrajectoryElement> trjElement;
                vector<int> idTrjElement;
                double t1 = 0.0, t2 = 0.0, t3 = 0.0;
                double e = Optimize( &trjElement, &idTrjElement, &reserve, idxSec, idxSet, 20, &infoTrj, &pointIdxToTrjNo, rnvtrjParam, &t1, &t2, &t3 );
                if( e >= 0.0 && ( min < 0.0 || e < min ) ) {
                    optOfSec = trjElement;
                    idOptOfSec = idTrjElement;
                    idxMinSet = idxSet;
                    min = e;
                }
            }
            cerr << " Optimization result: Set" << idxMinSet << endl;
            cerr << "    # of trajectories " << optOfSec.size() << endl;

            opt.insert( opt.end(), optOfSec.begin(), optOfSec.end() );
            idOpt.insert( idOpt.end(), idOptOfSec.begin(), idOptOfSec.end() );
        }

//#define RE_RENOVATE
#ifdef RE_RENOVATE
        //
        // $B:F=$I|$r9T$&(B
        //if( myRank == 0 ) {
            cerr << "  Re-renovation";
        //}

        // $B5a$a$?:GE,2r$r%;%C%H(B
        infoTrj.trjElement = opt;

        // $BM=Ls50@W$r5a$a$k(B
        reserve.clear();
        for( int idx = 0; idx < (int)idOpt.size(); ++idx ) {
            if( idOpt[ idx ] != -1 ) {
                reserve[ idx ] = idOpt[ idx ];
            }
        }

        // $B%;%/%7%g%sJ,3d(B
        DivideIntoSections( &infoTrj, rnvtrjParam );

        // $B3F%;%/%7%g%s$G%;%C%H$r:n@.(B
        for( int i = 0; i < (int)infoTrj.section.size(); ++i ) {
            MakeSet( i, &infoTrj, &reserve );
        }

        // $B:GE,2r$NC5:w(B
        opt.clear();
        idOpt.clear();
        min = -1.0;
        for( int idxSec = 0; idxSec < (int)infoTrj.section.size(); ++idxSec ) {
            min = -1.0;
            int idxMinSet = -1;
            vector<TrajectoryElement> optOfSec;
            vector<int> idOptOfSec;
            for( int idxSet = 0; idxSet < (int)infoTrj.section[ idxSec ].trjSet.size(); ++idxSet ) {
                vector<TrajectoryElement> trjElement;
                vector<int> idTrjElement;
                double t1 = 0.0, t2 = 0.0, t3 = 0.0;
                double e = Optimize( &trjElement, &idTrjElement, &reserve, idxSec, idxSet, 100/*20*/, &infoTrj, rnvtrjParam, &t1, &t2, &t3 );
                if( e >= 0.0 && ( min < 0.0 || e < min ) ) {
                    optOfSec = trjElement;
                    idOptOfSec = idTrjElement;
                    idxMinSet = idxSet;
                    min = e;
                }
            }

            opt.insert( opt.end(), optOfSec.begin(), optOfSec.end() );
            idOpt.insert( idOpt.end(), idOptOfSec.begin(), idOptOfSec.end() );
        }

        //if( myRank == 0 ) {
            cerr << "  Done..." << endl;
        //}
#endif

	    logTracking.renovation( TrackingProcessLogger::End );
        viewer.SetTrackingStatus( 3 );

        logTracking.finishing( TrackingProcessLogger::Start );

        // ID未割り当ての軌跡に新しいIDを振る
        for( vector<int>::iterator itID = idOpt.begin(); itID != idOpt.end(); ++itID ) {
            if( *itID == -1 ) {
                *itID = idNext;
                ++idNext;
            }
        }

        // 軌跡の補間を行う
        for( vector<TrajectoryElement>::iterator itTrj = opt.begin(); itTrj != opt.end(); ++itTrj ) {
            TrajectoryElement::iterator it = itTrj->begin();
            TrajectoryElement::iterator itNext = it;
            advance( itNext, 1 );
            while( itNext != itTrj->end() ) {
                while( it->t + commonParam.intervalTrajectory < itNext->t ) {
                    PosXYT pos;
                    pos.x = ( itNext->x - it->x ) / ( (double)( itNext->t - it->t ) * 1.0e-6 ) * ( (double)commonParam.intervalTrajectory * 1.0e-6 ) + it->x;
                    pos.y = ( itNext->y - it->y ) / ( (double)( itNext->t - it->t ) * 1.0e-6 ) * ( (double)commonParam.intervalTrajectory * 1.0e-6 ) + it->y;
                    pos.t = it->t + commonParam.intervalTrajectory;
                    it = itTrj->insert( it, pos );
                }
                ++it;
                ++itNext;
            }
        }

        // 結果の保存
        p_result->clear();
        resultTrajectory.clear();
        vector<int>::iterator itID = idOpt.begin();
        for( vector<TrajectoryElement>::iterator itTrj = opt.begin(); itTrj != opt.end(); ++itTrj, ++itID ) {
            int id = ( *itID == -1 ) ? idNext++ : *itID;
            CTrajectory trj;
            trj.push_back( *itTrj );
            resultTrajectory[ id ] = trj; // resultTrajectory$B$O<!2s$NDI@W$K$b;H$&$N$G>/$7D9$$(B
            //trj.Clip( 0, timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ) );
            //(*p_result)[ id ] = trj; // $BI=<(MQ(B
        }

        //map<unsigned long long, multimap<int,Point2d> > ext_result;

        unsigned long long time;
        p_ext_result->insert( remainedExtendedResult.begin(), remainedExtendedResult.end() );
        for( /*unsigned long long*/ time = max( timeTracking - commonParam.termTracking, timeEarliestPEPMap )
                ; time < timeTracking - ( commonParam.termTracking - commonParam.intervalTracking )
                ; time += commonParam.intervalTrajectory ) {

            (*p_result)[ time ];
            (*p_ext_result)[ time ];

            const set<TIME_MICRO_SEC>::iterator it_start_pepmap_time = time_of_received_pepmap.lower_bound( time );
            const set<TIME_MICRO_SEC>::iterator it_end_pepmap_time = time_of_received_pepmap.lower_bound( time + commonParam.intervalTrajectory );
            for( set<TIME_MICRO_SEC>::iterator it = it_start_pepmap_time; it != it_end_pepmap_time; ++it ) {
               (*p_ext_result)[ *it ]; 
            }

            map<int,CTrajectory>::const_iterator itResult = resultTrajectory.begin();
            for( ; itResult != resultTrajectory.end(); ++itResult ) {
                const CTrajectory& trajectory = itResult->second;
                if( trajectory.size() > 0 ) {
                    TrajectoryElement::iterator itPos = trajectory.front().begin();
                    for( ; itPos != trajectory.front().end(); ++itPos ) {
                        if( itPos->t == time ) {
                            (*p_result)[ time ][ itResult->first ] = Point2d( itPos->x, itPos->y );

                            const int trj_no = itPos->ID;
                            if( trj_no < trajectoriesClustered.size() ) {
                                for( CTrajectory::iterator it = trajectoriesClustered[ trj_no ].begin()
                                   ; it != trajectoriesClustered[ trj_no ].end(); ++it ) {
                                    TrajectoryElement::iterator itPos2;
                                    if( ( itPos2 = it->find( PosXYT( 0.0, 0.0, time ) ) ) != it->end() ) {
                                        (*p_ext_result)[ time ].insert( pair<int,Point2d>( itResult->first, Point2d( itPos2->x, itPos2->y ) ) );
                                        PosXYT pos0, pos1;
                                        pos0 = *itPos2;
                                        advance( itPos2, 1 );
                                        if( itPos2 != it->end() ) {
                                            pos1 = *itPos2;
                                            for( set<TIME_MICRO_SEC>::iterator it = it_start_pepmap_time; it != it_end_pepmap_time; ++it ) {
                                                PosXYT pos;
                                                pos.x = ( pos1.x - pos0.x ) / ( (double)( pos1.t - pos0.t ) ) * ( (double)( *it - *it_start_pepmap_time ) ) + pos0.x;
                                                pos.y = ( pos1.y - pos0.y ) / ( (double)( pos1.t - pos0.t ) ) * ( (double)( *it - *it_start_pepmap_time ) ) + pos0.y;
                                                (*p_ext_result)[ *it ].insert( pair<int,Point2d>( itResult->first, Point2d( pos.x, pos.y ) ) );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        remainedExtendedResult.clear();
        for( ; time < timeTracking; time += commonParam.intervalTrajectory ) {
            const set<TIME_MICRO_SEC>::iterator it_start_pepmap_time = time_of_received_pepmap.lower_bound( time );
            const set<TIME_MICRO_SEC>::iterator it_end_pepmap_time = time_of_received_pepmap.lower_bound( time + commonParam.intervalTrajectory );

            map<int,CTrajectory>::const_iterator itResult = resultTrajectory.begin();
            for( ; itResult != resultTrajectory.end(); ++itResult ) {
                const CTrajectory& trajectory = itResult->second;
                if( trajectory.size() > 0 ) {
                    TrajectoryElement::iterator itPos = trajectory.front().begin();
                    for( ; itPos != trajectory.front().end(); ++itPos ) {
                        if( itPos->t == time ) {
                            //(*p_result)[ time ][ itResult->first ] = Point2d( itPos->x, itPos->y );

                            const int trj_no = itPos->ID;
                            //if( trj_no < trajectoriesClustered.size() ) {
                                for( CTrajectory::iterator it = trajectoriesClustered[ trj_no ].begin()
                                   ; it != trajectoriesClustered[ trj_no ].end(); ++it ) {
                                    TrajectoryElement::iterator itPos2;
                                    if( ( itPos2 = it->find( PosXYT( 0.0, 0.0, time ) ) ) != it->end() ) {
                                        (*p_ext_result)[ time ].insert( pair<int,Point2d>( itResult->first, Point2d( itPos2->x, itPos2->y ) ) );
                                        PosXYT pos0, pos1;
                                        pos0 = *itPos2;
                                        advance( itPos2, 1 );
                                        if( itPos2 != it->end() ) {
                                            pos1 = *itPos2;
                                            for( set<TIME_MICRO_SEC>::iterator it = it_start_pepmap_time; it != it_end_pepmap_time; ++it ) {
                                                PosXYT pos;
                                                pos.x = ( pos1.x - pos0.x ) / ( (double)( pos1.t - pos0.t ) ) * ( (double)( *it - *it_start_pepmap_time ) ) + pos0.x;
                                                pos.y = ( pos1.y - pos0.y ) / ( (double)( pos1.t - pos0.t ) ) * ( (double)( *it - *it_start_pepmap_time ) ) + pos0.y;
                                                remainedExtendedResult[ *it ].insert( pair<int,Point2d>( itResult->first, Point2d( pos.x, pos.y ) ) );
                                            }
                                        }
                                    }
                                }
                            //}
                        }
                    }
                }
            }       
        }


        viewer.SetResult( *p_result );

        //
        // Output process information of renovation
        //if( myRank == 0 ) {
        if( flgOutputTrackingProcessData2Files ) {
            {
                double sumValue = accumulate( sampler.begin(), sampler.end(), 0.0, PosXYTV_Sum() );
                unsigned int nSample = (unsigned int)( plotParam.kSample /*3.0e-2*//*1.04e-4*/ * sumValue );
                OutputProcess( timeTracking - commonParam.termTracking//tableLUMSlice.begin()->first
                             , timeTracking//tableLUMSlice.rbegin()->first
                             , timeEarliestPEPMap
                             , &sampler
                             , nSample
                             , &resultTrajectory
                             , NULL
                             , &plotParam );
            }
        }

        delete [] distTable;

        //
        // sampler
        sampler.erase( sampler.begin()
                        , lower_bound( sampler.begin()
                                    , sampler.end()
                                    , pair<PosXYT,unsigned long>( PosXYT( 0.0, 0.0, timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ) ), 0 )
                                    , PosXYT_T_Less() ) );

        //
        // storageLUM
        storageLUM.erase( storageLUM.begin()
                        , storageLUM.lower_bound( timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ) ) );

        //
        // tableLUMSlice
        tableLUMSlice.erase( tableLUMSlice.begin()
                            , tableLUMSlice.lower_bound( timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ) ) );


        //
        // storageTrajectoryElement
        // [timeTracking - commonParam.termTracking, timeTracking]$B$K%/%j%C%T%s%0(B
        CTrajectory newStorageTrajectoryElement;
        newStorageTrajectoryElement.assign( storageTrajectoryElement.begin(), storageTrajectoryElement.end() );
        newStorageTrajectoryElement.Clip( timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ), timeTracking );
        storageTrajectoryElement.assign( newStorageTrajectoryElement.begin(), newStorageTrajectoryElement.end() );

        time_of_received_pepmap.erase( time_of_received_pepmap.begin()
                                     , time_of_received_pepmap.lower_bound( timeTracking - ( commonParam.termTracking - commonParam.intervalTracking ) ) );


        //prevTrajectoriesClustered = trajectoriesClustered;


        timeTracking += commonParam.intervalTracking;

        ret = true;

        logTracking.finishing( TrackingProcessLogger::End );

        logTracking.end_and_output2file();
        flgTrackingStarts = true;
    }

    return ret;
}
Example #4
0
File: 256e.cpp Project: 199911/acm
int pred( int x ) {
  set<int>::iterator it = S.lower_bound( x );
  --it;
  return *it;
}
Example #5
0
int main()
{
  freopen("ti.in","r",stdin);
  scanf("%d",&zu);
  for (zz=1;zz<=zu;zz++)
  {
    memset(f,0,sizeof(f));
    mm=0;
    shu[0]=0;
    s.clear();
    // cout<<s.size()<<endl;
    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
      scanf("%d",&shu[i]);
      mm=max(mm,shu[i]);
    }
    tt.p=0;
    tt.d=0;
    s.insert(tt);
    mm=1;
    for (i=1;i<=n;i++)
    {
      if (shu[i-1]<shu[i])
      {
        f[i][0]=f[i-1][0]+1;
        f[i][1]=f[i-1][1]+1;
      }
      else
      {
        f[i][0]=1;
        f[i][1]=1;
      }
      mm=max(mm,f[i][0]);
      tt.p=shu[i];
      tt.d=f[i][0];
      // cout<<s.size()<<endl;
      set<D>::iterator it;
      if (s.size()!=1)
      {
        it=s.lower_bound(tt);
        it--;
      }
      else
        it=s.begin();
      //if (((*it).p==tt.p)&&(it!=s.begin()))
      //  it--;
      f[i][1]=max(f[i][1],(*it).d+1);
      mm=max(mm,f[i][1]);
      if (s.size()!=1)
      {
        it=s.lower_bound(tt);
        it--;
      }
      else
        it=s.begin();
      //if (it==s.end())
      // it--; //非常重要!
      if ((*it).p==shu[i])
      {
        if ((*it).d<f[i][0])
        {
          s.erase(it);
          s.insert(tt);
        }
      }
      else
      {
        if (f[i][0]>(*it).d)
        {
          it=(s.insert(tt)).first;
          it++;
          for (;it!=s.end();)
          {
            if ((*it).d<f[i][0])
              s.erase(it++);
            else
              break;
          }
        }
      }
    }
    cout<<mm<<endl;
  }
  return 0;
}
Example #6
0
int main() {

    while (cin >> n >> m) {
        pt.clear();
        for (int i = 0; i < n; i++) {
            int ta, tb;
            cin >> ta >> tb;
            pt.push_back(rec(ta, tb));
        }
        sort(pt.begin(), pt.end());
        ep.clear();
        for (int i = 0; i < n; i++) {
            while (ep.size() != 0 && pt[i].b <= (*(ep.end() - 1)).b) ep.pop_back();
            ep.push_back(pt[i]);
        }

        sct.clear();
        for (int i = 0; i != ep.size(); i++) {
            sct.push_back(rec(ep[i].a, 2 * i));
            sct.push_back(rec(ep[i].b, 2 * i + 1));
        }
        sort(sct.begin(), sct.end());

        sca.clear();
        sc.resize(ep.size());
        for (int i = 0; i != sct.size(); i++) {
            if (i == 0 || sct[i].a != sct[i - 1].a)
                sca.push_back(sct[i].a);
            if (sct[i].b & 1) sc[sct[i].b / 2].b = sca.size() - 1;
            else sc[sct[i].b / 2].a = sca.size() - 1;
        }

        qa.clear();
        qb.clear();
        for (int i = 0; i < m; i++) {
            int ta, tb;
            cin >> ta >> tb;
            qa.push_back(rec(ta, i));
            qb.push_back(rec(tb, i));
        }

        sort(qa.begin(), qa.end());
        sort(qb.begin(), qb.end());

        oa.resize(m);
        ob.resize(m);

        int pa = 0;
        for (int i = 0; i != qa.size(); i++) {
            while (pa != sca.size() && sca[pa] < qa[i].a) pa++;
            if (pa == sca.size()) oa[qa[i].b] = INF;
            else oa[qa[i].b] = pa;
        }

        int pb = sca.size() - 1;
        for (int i = qb.size() - 1; i >= 0; i--) {
            while (pb >= 0 && sca[pb] > qb[i].a) pb--;
            if (pb == -1) ob[qa[i].b] = -INF;
            else ob[qb[i].b] = pb;
        }

        ss.clear();
        for (int i = 0; i != sc.size(); i++) ss.insert(sc[i]);
        ss.insert(rec(sca.size(), sca.size()));

        for (int i = 0; i != sca.size(); i++) {
            f[0][i] = (*ss.lower_bound(rec(i, INF))).b;
        }
        for (int i = 0; i < 20; i++)
            f[i][sca.size()] = sca.size();

        for (int i = 1; i < 20; i++)
            for (int j = 0; j != sca.size(); j++)
                f[i][j] = f[i - 1][f[i - 1][j]];

        for (int i = 0; i < m; i++) {
            cout << query(oa[i], ob[i]) << endl;
        }
    }
    return 0;
}
Example #7
0
int main( int argc, char* argv[] ){

	ios::sync_with_stdio( false );
	
	int Q, x, i, j;
	
	cin >> N >> Q;
	h.insert( segt( 1, N ) );
	
	while( Q-- ){
		cin >> x;
		if( x ){
			
			if( put[x] ){
				
				int pos = put[x];
				TI( used ) itnxt, itprv;
				itnxt = used.upper_bound( pos );
				itprv = used.lower_bound( pos );
				
				int nxt, prv;
				nxt = prv = -1;
				if( itprv != used.begin() ){
					itprv--;
					prv = *itprv;
				} else {
					prv = 0;
				}
				
				if( itnxt != used.end() ){
					nxt = *itnxt;
				} else {
					nxt = N+1;
				}
				
				used.erase( pos );
				put.erase( x );
				down( pos );
				
				int from, to;
				from = to = pos;
				
				if( nxt != pos+1 ){
					h.erase( segt( pos+1, nxt-1 ) );
					to = nxt-1;
				}
				
				if( prv+1 != pos ){
					h.erase( segt(prv+1, pos-1) );
					from = prv+1;
				}
				
				h.insert( segt( from, to ) );
						
			} else {
				segt fre = *(h.begin());
				h.erase( h.begin() );	
				
				int pos = fre.first + (fre.second-fre.first+1)/2;
				
				put[x] = pos;
				used.insert( pos );
				up( pos );
				
				if( pos-1 >= fre.first ) h.insert( segt( fre.first, pos-1 ) );
				if( pos+1 <= fre.second ) h.insert( segt( pos+1, fre.second ) );	
			}
			
		} else {
			cin >> i >> j;
			cout << get(j) - get(i-1) << "\n";
		}
	}
	
	return 0;
}
Example #8
0
int get(int gain){//minimo costo de obtener tal ganancia
	set<V>::iterator p=s.lower_bound((V){gain, 0});
	return p==s.end()? INF : p->cost;}
Example #9
0
void preWork() //用平衡二叉树预处理得到每个城市的最小和次小差值的城市
{
    for(int i=n;i>=1;i--) //由于车子只能从之前的城市移动到后面的城市,所以得倒着找前驱后继
    {
        bst.insert(h[i]);
		/*	找到最接近h(i)的两个元素
			lower返回大于等于的第个数,再自减得到最大的小于的数
			upper返回小于等于的最后一个元素的后一个元素----返回大于它的数

			用这种方法是为了取的不等于的数*/
        city[1].h=*--bst.lower_bound(h[i]),city[2].h=*bst.upper_bound(h[i]);
        if(city[1].h>-INF)
			//存在比h(i)更小的数,找到第二小的数
			city[3].h=*--bst.lower_bound(city[1].h);
        else city[3].h=-INF;
		
		//同上一条笔记
        if(city[2].h<INF) city[4].h=*bst.upper_bound(city[2].h);
        else city[4].h=INF;
        for(int k=1;k<=4;k++)
			//相对高度
            city[k].dec=abs(city[k].h-h[i]);
		
		//根据比较函数,会优先选择相对高度更小的,如果相对高度相同,会让海拔更低的放在前面
        sort(city+1,city+5); //排序
		
		//根据题目分别把第二的给a,第一的给b
        a[i]=city[2].dec;
        fa[i]=hash[city[2].h];
        b[i]=city[1].dec;
        fb[i]=hash[city[1].h];
        for(int j=0;j<=16;j++)
        {
            if(j==0) //一个轮回
            {
                if(fa[i])
                {
                    va[i][0]=a[i];
                    to[i][0]=fa[i];
                }
            }
            else if(j==1) //2^1=2个轮回
			/*	一个轮回—a或b开一次车?
				但仅有这个解释能理解&说通*/
            {
                if(fb[fa[i]])
                {
                    va[i][1]=a[i];
                    vb[i][1]=b[fa[i]];
                    to[i][1]=fb[fa[i]];
                }
            }
            else if(to[to[i][j-1]][j-1]) //2^x,x>1,倍增来求答案
            {
                va[i][j]=va[i][j-1]+va[to[i][j-1]][j-1];
                vb[i][j]=vb[i][j-1]+vb[to[i][j-1]][j-1];
                to[i][j]=to[to[i][j-1]][j-1];
            }
            else break;
        }
    }
}
Example #10
0
int main()
{
    for(int i=0;i<10;i++) n[i].clear();

    n[1].insert(1);
    n[1].insert(2);
    n[1].insert(3);
    n[1].insert(4);
    n[1].insert(5);
    n[1].insert(6);
    n[1].insert(7);
    n[1].insert(8);
    n[1].insert(9);
    n[1].insert(0);

    n[2].insert(2);
    n[2].insert(3);
    n[2].insert(5);
    n[2].insert(6);
    n[2].insert(8);
    n[2].insert(9);
    n[2].insert(0);

    n[3].insert(3);
    n[3].insert(6);
    n[3].insert(9);

    n[4].insert(4);
    n[4].insert(5);
    n[4].insert(6);
    n[4].insert(7);
    n[4].insert(8);
    n[4].insert(9);
    n[4].insert(0);

    n[5].insert(5);
    n[5].insert(6);
    n[5].insert(8);
    n[5].insert(9);
    n[5].insert(0);

    n[6].insert(6);
    n[6].insert(9);

    n[7].insert(7);
    n[7].insert(8);
    n[7].insert(9);
    n[7].insert(0);

    n[8].insert(8);
    n[8].insert(9);
    n[8].insert(0);

    n[9].insert(9);

    n[0].insert(0);

    s.clear();
    rs.clear();

    for(int i=0;i<=999;i++)
    if(judge(i))
    {
        s.insert(i);
        rs.insert(i);
    }

    scanf("%d",&t);

    while(t--)
    {
        scanf("%d",&x);

        int nxt = *(s.lower_bound(x));
        int pre = *(rs.lower_bound(x));

        if(nxt - x > x - pre)
            printf("%d\n" , pre);
        else
            printf("%d\n" , nxt);
    }
    return 0;
}
Example #11
0
int main() {
  int que;
  scanf("%d", &que);
  for (int i = 0; i < que; i++) {
    scanf("%d %d %d", t+i, &p[i].x, &p[i].y);
    if (t[i]) {
      scanf("%d %d", &q[i].x, &q[i].y);
    }
    else {
      vp.push_back(make_pair(p[i], i));
    }
  }
  sort(vp.begin(), vp.end());
  for (int i = 0; i < vp.size(); i++)
    id[vp[i].second] = i+1;
  fen bup(vp.size() + 2), blow(vp.size()+ 2);
  for (int i = 0; i < que; i++) {
    if (t[i] == 0) {
      pair<point, int> now = make_pair(p[i], id[i]);
      lower.insert(now);
      set<pair<point, int> >::iterator it = lower.lower_bound(now);
      if (baddown(it))
        lower.erase(it);
      else {
        blow.upd(now.second, +1);
        set<pair<point, int> >::iterator nx = it;
        nx++;
        while (nx != lower.end() && baddown(nx)) {
          blow.upd(nx->second, -1);
          lower.erase(nx++);
        }
        nx = it;
        while (nx != lower.begin()) {
          nx--;
          if (baddown(nx)) {
            blow.upd(nx->second, -1);
            lower.erase(nx);
            nx = it;
          }
          else
            break;
        }
      }

      // upper
      upper.insert(now);
      it = upper.lower_bound(now);
      if (badup(it))
        upper.erase(it);
      else {
        bup.upd(now.second, +1);
        set<pair<point, int> >::iterator nx = it;
        nx++;
        while (nx != upper.end() && badup(nx)) {
          bup.upd(nx->second, -1);
          upper.erase(nx++);
        }
        nx = it;
        while (nx != upper.begin()) {
          nx--;
          if (badup(nx)) {
            bup.upd(nx->second, -1);
            upper.erase(nx);
            nx = it;
          }
          else
            break;
        }
      }
    }
    else {
      int ans = 1, tot = (int)upper.size() + (int)lower.size() - 4;
      set<pair<point, int> >::iterator lowa = lower.lower_bound(make_pair(p[i], -1)), lowb = lower.lower_bound(make_pair(q[i], -1));
      set<pair<point, int> >::iterator upa = upper.lower_bound(make_pair(p[i], -1)), upb = upper.lower_bound(make_pair(q[i], -1));
      if (lowa != lower.end() && lowb != lower.end() && lowa->first == p[i] && lowb->first == q[i]) {
        int d = blow.get(lowb->second) - blow.get(lowa->second);
        if (d > 0) {
          d--;
          ans = (tot-d >= d);
        }
        else {
          d = -d - 1;
          ans = (d >= tot-d);
        }
      }
      else if (upa != upper.end() && upb != upper.end() && upa->first == p[i] && upb->first == q[i]) {
        int d = bup.get(upb->second) - bup.get(upa->second);
        if (d > 0) {
          d--;
          ans = (d >= tot-d);
        }
        else {
          d = -d - 1;
          ans = (tot-d >= d);
        }
      }
      else if (lowa != lower.end() && upb != upper.end() && lowa->first == p[i] && upb->first == q[i]) {
        int d = blow.get(lowa->second) + bup.get(upb->second) - 3;
        ans = (d >= tot-d);
      }
      else if (upa != upper.end() && lowb != lower.end() && upa->first == p[i] && lowb->first == q[i]) {
        int d = blow.get(lowb->second) + bup.get(upa->second) - 3;
        ans = (tot-d >= d); 
      }
      else {
        cerr << "Ooops!" << endl;
        assert(false);
      }
      puts(ans ? "CW" : "CCW");
    }
  }
  return 0;
}
Example #12
0
int main(){
	ios_base::sync_with_stdio(false);
	cin >> w >> h >> n;
	
	cuth.insert(0);
	cuth.insert(h);
	dh.insert(MP(h, 1));
	
	cutv.insert(0);
	cutv.insert(w);
	dv.insert(MP(w, 1));

	while(n--){
		char fi;
		int se;
		cin >> fi >> se;
		if(fi == 'H'){
			init it1 = cuth.lower_bound(se), it2 = it1;
			it1--;
			int dis1 = se - (*it1),
				dis2 = (*it2) - se;
			pit it3 = dh.lower_bound(MP((*it2) - (*it1), 0));
			dh.erase(it3);
			pie t = *it3;
			t.R--;
			if(t.R)
				dh.insert(t);

			it3 = dh.lower_bound(MP(dis1, 0));
			if(it3 == dh.end() or it3->L != dis1)
				dh.insert(MP(dis1, 1));
			else{
				t = *it3;
				dh.erase(it3);
				t.R++;
				dh.insert(t);
			}
			it3 = dh.lower_bound(MP(dis2, 0));
			if(it3 == dh.end() or it3->L != dis2)
				dh.insert(MP(dis2, 1));
			else{
				t = *it3;
				dh.erase(it3);
				t.R++;
				dh.insert(t);
			}
			cuth.insert(se);
		}		
		else{
			init it1 = cutv.lower_bound(se), it2 = it1;
			it1--;
			int dis1 = se - (*it1),
				dis2 = (*it2) - se;
			pit it3 = dv.lower_bound(MP((*it2) - (*it1), 0));
			dv.erase(it3);
			pie t = *it3;
			t.R--;
			if(t.R) dv.insert(t);

			it3 = dv.lower_bound(MP(dis1, 0));
			if(it3 == dv.end() or it3->L != dis1)
				dv.insert(MP(dis1, 1));
			else{
				t = *it3;
				dv.erase(it3);
				t.R++;
				dv.insert(t);
			}
			it3 = dv.lower_bound(MP(dis2, 0));
			if(it3 == dv.end() or it3->L != dis2)
				dv.insert(MP(dis2, 1));
			else{
				t = *it3;
				dv.erase(it3);
				t.R++;
				dv.insert(t);
			}
			cutv.insert(se);
		}
		pit ith = dh.end(), itv = dv.end();
		ith--;
		itv--;
		cout << 1LL * (ith->L) * (itv->L) << endl;
	}

	return 0;
}
Example #13
0
int main(){
    freopen("in.txt", "r", stdin);
    freopen("outstd.txt", "w", stdout);
    int _;
    scanf("%d", &_);
    while (_--){
        scanf("%d", &n);
        for (int i = 1; i <= n; ++ i){
            scanf("%d", &l[i]);
        }
        for (int i = 1; i <= n; ++ i){
            scanf("%d", &r[i]);
        }
        for (int i = 1; i <= n; ++ i){
            scanf("%d", &c[i]);
        }
        from.clear();
        now.clear();
        for (int i = 1; i <= n; ++ i){
            dp[i] = -1;
        }

        from.insert(Node(c[1], 1));
        dp[1] = 0;
        for (int i = 2; i <= n; ++ i){
            now.insert(i);
        }

        while (!from.empty()){
            int k = (*from.begin()).id; from.erase(from.begin());

            wait.clear();
            set<int>::iterator it = now.lower_bound(l[k] + k);
            while (it != now.end()){
                int to = (*it);
                if (to > r[k] + k) break;
                dp[to] = dp[k] + 1ll * c[k];
                wait.push_back(to);
                ++ it;
            }
            for (int i = 0; i < wait.size(); ++ i){
                now.erase(wait[i]);
                from.insert(Node(dp[wait[i]] + 1ll * c[wait[i]], wait[i]));
            }

            wait.clear();
            it = now.upper_bound(k - l[k]);
            if (it == now.begin()) continue;
            do{
                -- it;
                int to = (*it);
                if (to < k - r[k]) break;
                dp[to] = dp[k] + 1ll * c[k];
                wait.push_back(to);                
            }while(it != now.begin());
            for (int i = 0; i < wait.size(); ++ i){
                now.erase(wait[i]);
                from.insert(Node(dp[wait[i]] + 1ll * c[wait[i]], wait[i]));
            }
        }
        for (int i = 1; i <= n; ++ i){
            printf("%lld%c", dp[i], i == n ? '\n' : ' ');
        }
    }
    return 0;
}
Example #14
0
int main()
{
	scanf("%d%d%d%d%d%d",&n,&m,&t,&tp,&tu,&td);
	int x0,y0,x1,y1,ans=0x7fffffff,val1,val2;
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
		{
			scanf("%d",&M[i][j]);
			if (M[i][j]==M[i][j-1])
				L[i][j]=L[i][j-1]+tp,R[i][j]=R[i][j-1]+tp;
			else if (M[i][j]<M[i][j-1])
				L[i][j]=L[i][j-1]+td,R[i][j]=R[i][j-1]+tu;
			else if (M[i][j]>M[i][j-1])
				L[i][j]=L[i][j-1]+tu,R[i][j]=R[i][j-1]+td;
			//=.= 0.0 -.- ←_← →_→QwQ OAO OvO
			if (M[i][j]==M[i-1][j])
				U[i][j]=U[i-1][j]+tp,D[i][j]=D[i-1][j]+tp;
			else if (M[i][j]<M[i-1][j])
				U[i][j]=U[i-1][j]+td,D[i][j]=D[i-1][j]+tu;
			else if (M[i][j]>M[i-1][j])
				U[i][j]=U[i-1][j]+tu,D[i][j]=D[i-1][j]+td;
		}
	}
	spiii tans;
	pair<int,int> last;
	for (int i=1;i<=n;i++)
		for (int j=i+2;j<=n;j++)
		{
			for (int k=1;k<=m;k++)
			{
				if (k>=3)
				{
					val1=U[j][k]-U[i][k]+L[i][k]+R[j][k];
					tans=S.lower_bound(make_pair(t-(U[j][k]-U[i][k]+L[i][k]+R[j][k]),k));
					if (tans!=S.end())
					{
						if (abs(val1+tans->first-t)<abs(ans-t))
						{
							ans=val1+tans->first;
							x0=i,x1=j,y0=tans->second,y1=k;
						}
					}
					if (tans!=S.begin())
					{
						tans--;
						if (abs(val1+tans->first-t)<abs(ans-t))
						{
							ans=val1+tans->first;
							x0=i,x1=j,y0=tans->second,y1=k;
						}
					}
				}
				if (k>1)
					S.insert(last);
				last=make_pair(D[j][k]-D[i][k]-L[i][k]-R[j][k],k);
			}
			S.clear();
		}
	printf("%d %d %d %d\n",x0,y0,x1,y1);
/*	for (int i=1;i<=n;i++,printf("\n"))
		for (int j=1;j<=m;j++)
			printf("%d\t",L[i][j]);
			printf("\n");
	for (int i=1;i<=n;i++,printf("\n"))
		for (int j=1;j<=m;j++)
			printf("%d\t",R[i][j]);
			printf("\n");
	for (int i=1;i<=n;i++,printf("\n"))
		for (int j=1;j<=m;j++)
			printf("%d\t",U[i][j]);
			printf("\n");
	for (int i=1;i<=n;i++,printf("\n"))
		for (int j=1;j<=m;j++)
			printf("%d\t",D[i][j]);
	int a,b,c,d;
	while (~scanf("%d%d%d%d",&a,&b,&c,&d))
	{
		printf("%d\n",L[a][d]-L[a][b]+U[c][d]-U[a][d]+R[c][d]-R[c][b]+D[c][b]-D[a][b]);
	}*/
	return 0;
}
Example #15
0
int main()
{
	scanf("%d %d %d", &d, &n, &m);

	for (int i = 0; i < m; ++i)
		scanf("%d %d", &a[i].x, &a[i].p);

	sort(a, a+m);

	segs.insert(pii(0, min(n, d)));

	// for (it = segs.begin(); it != segs.end(); ++it)
	// 		printf("[%d %d] ", (*it).F, (*it).S);
	// 	printf("\n");

	for (int i = 0; i < m; ++i)
	{
		it2 = it = segs.lower_bound(pii(a[i].x + 1, -1));
		pii p1, p2;
		if (it == segs.end())
			p1 = pii(d, d);
		else
			p1 = *it;

		--it2;
		p2 = *it2;

		if (p2.S - a[i].x >= n)
			continue;

		if (a[i].x > p2.S)
		{
			if (a[i].x + n < p1.F)
			{
				res += (ll)n * a[i].p;
				segs.insert(pii(a[i].x, a[i].x + n));
			}
			else
			{
				res += (ll)(p1.F - a[i].x) * a[i].p;
				if (it != segs.end())
					segs.erase(it);
				segs.insert(pii(a[i].x, p1.S));
			}
		}
		else
		{
			if (a[i].x + n < p1.F)
			{
				res += (ll)(a[i].x + n - p2.S) * a[i].p;
				segs.erase(it2);
				segs.insert(pii(p2.F, a[i].x + n));
			}
			else
			{
				res += (ll)(p1.F - p2.S) * a[i].p;
				if (it != segs.end())
					segs.erase(it);
				segs.erase(it2);
				segs.insert(pii(p2.F, p1.S));
			}
		}

		// for (it = segs.begin(); it != segs.end(); ++it)
		// 	printf("[%d %d] ", (*it).F, (*it).S);
		// printf("\n");
	}

	if (segs.size() != 1)
		res = -1;
	else if ((*segs.begin()).second != d)
			res = -1;

	printf("%lld", res);
	return 0;
}
bool get(int x, int y) {
  auto it = um.lower_bound(x);
  return it == um.end() || *it >= y;
}
    void addNum(int val) 
    {
        int flag=0;
        int a,b;
        
        // 空集特殊处理
        if (Set.size()==0)
        {
            Set.insert(Interval(val,val));
            return;
        }
        
        
        // 如果已经存在于已有的区间中,那么什么都不用做
        auto it = Set.lower_bound(Interval(val,val));            
        if (val>=it->start && val<=it->end)
            return;        
        
        if (it!=Set.begin())
        {
            it--;
            if (val>=it->start && val<=it->end)
                return;
        }
            
        // 如果可以与一个区间相接,那么更新那个区间
        it = Set.lower_bound(Interval(val,val));
        if (it!=Set.begin())
        {
            it--;
            if (it->end==val-1)
            {
                a = it->start;
                b = val;
                Set.erase(it);
                Set.insert(Interval(a,b));
                flag=1;
            }
        }
        

        it = Set.lower_bound(Interval(val,val));
        if (it!=Set.end() && it->start==val+1)
        {
            a = val;
            b = it->end;
            Set.erase(it);
            Set.insert(Interval(a,b));
            flag++;
        }
        
        // 如果更新了两个区间,说明这两个区间可以拼接起来。
        if (flag==2)
        {
            it = Set.lower_bound(Interval(val,val));
            if (it!=Set.begin() && it!=Set.end())
            {
                auto it0=it;
                it0--;
                if (it0->end==it->start)
                {
                    a=it0->start;
                    b=it->end;
                    Set.erase(it0);
                    Set.erase(it);
                    Set.insert(Interval(a,b));
                }
            }
        }
        // 没有相邻接的区间可以更新,那么就自己单独作为一个区间
        else if (flag==0)
        {
            Set.insert(Interval(val,val));
        }
        
        
    }
Example #18
0
int main (){
	long N,x,y;
	cin >> N;
	for(long i = 0; i < N; i++){
		cin >> x >> y;
		list.push_back(make_pair(x,y));
	}

    //#ifdef hackpackpp
	//Sort the elements on increasing y values
    //#endif
	sort(list.begin(),list.end(),SortOnY);

    //#ifdef hackpackpp
	//initialize variables
    //#endif
	set<pii>::iterator before, after;
	long area = 0;

    //#ifdef hackpackpp
	//Some times it is better to make a change than code an edge case
    //#endif
	myset.insert(make_pair(0,0));
	myset.insert(make_pair(1000000,0));

    //#ifdef hackpackpp
	//Use a sweep line based on the set
    //#endif
	for(vector<pii>::iterator it = list.begin(); it != list.end(); it++){
		myset.insert(*it);
		before = myset.lower_bound(*it);
		after = myset.upper_bound(*it);

        //#ifdef hackpackpp
		//lower_bound returns the pointer to the current element
		//decrement if it will be within bounds
        //#endif
		if(before != myset.begin()) before--;

        //#ifdef hackpackpp
		//compute the area of the box
        //#endif
		area = max(area,  it->second * (after->first - before->first));
	}


    //#ifdef hackpackpp
	//Check all of the plots that extend to the back of the plot
    //#endif
	after = myset.begin();
	for(before = myset.begin(); after != myset.end(); before++){
		after++;

        //#ifdef hackpackpp
		//compute the area of the long plots
        //#endif
		area = max(area, (after->first - before->first) * MAXHEIGHT);
	}

    //#ifdef hackpackpp
	//output according to the output spec
    //#endif
	cout << area << endl;
}
Example #19
0
inline int lft(int i) {
  auto it = ban.lower_bound(i);
  --it;
  return *it + 1;
}
Example #20
0
File: bits.cpp Project: ArturD/code
int get_bit_pos(set<int>& S, int position) {
    set<int>::iterator iter = S.lower_bound(position);
    if(iter == S.begin()) return -1;
    iter --;
    return *iter;
}
Example #21
0
int main()
{
    string op;
    int a;
    char b;
    while (cin >>n >>Q)
    {
        loc.clear();
        memset(t, 0, sizeof(t));
        cin >>s1;
        cin >>s2;
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        loc.insert(n+1);
        for (int i=0; i<n; i++)
        {
            if (s1[i] == '1') add(i+1, 1);
            if (s2[i] == '1') add(i+1, 1);
            if (s1[i] == '1' && s2[i] == '1') loc.insert(i+1);        
        }
        s1 += "0"; s2 += "0";
        while (Q--)
        {
            cin >>op;
            if (op == "set_a")
            {
                cin >>a >>b;
                if (s1[a] == b) continue;
                if (b == '1') 
                {
                    add(a+1, 1);
                    if (s2[a] == '1') loc.insert(a+1);
                    s1[a] = b;
                }
                else 
                {
                    add(a+1, -1);
                    if (s2[a] == '1')
                    {
                        loc.erase(loc.lower_bound(a+1));
                    }
                    s1[a] = b;
                }
                
            }
            else
            if (op == "set_b")
            {
                cin >>a >>b;
                if (s2[a] == b) continue;
                if (b == '1') 
                {
                    add(a+1, 1);
                    if (s1[a] == '1') loc.insert(a+1);
                    s2[a] = b;
                }
                else 
                {
                    add(a+1, -1);    
                    if (s1[a] == '1') loc.erase(loc.lower_bound(a+1));
                    s2[a] = b;
                }            
            }
Example #22
0
typename set<T>::iterator find(set<T> & c, const T & value) {
	return c.lower_bound(value);
}
Example #23
0
int main(){
    //freopen("input.txt","r",stdin);

    len=0;
    scanf("%s",s+len+1);
    len1=strlen(s+len+1);
    len+=len1;
    s[++len]='#';
    scanf("%s",s+len+1);
    len2=strlen(s+len+1);
    len+=len2;
    s[++len]='@';
    scanf("%s",s+len+1);
    len3=strlen(s+len+1);
    len+=len3;

    suffixArray();

    reset(sum,0);
    for(int i=1; i<=len; ++i){
        for(int j=0; j<3; ++j) sum[j][i]=sum[j][i-1];
        if(sa[i]<=len1) sum[0][i]++;
        else if(len1+1<sa[i] && sa[i]<=len1+1+len2) sum[1][i]++;
        else if(len1+len2+2<sa[i] && sa[i]<=len1+len2+2+len3) sum[2][i]++;
    }

    int last=0;
    for(int i=1; i<=len; ++i){
        while(last>0 && lcp[mys[last]] >= lcp[i]) --last;
        if(last==0) tl[i]=0; else tl[i]=mys[last];
        mys[++last]=i;
    }
    last=0;
    for(int i=len; i>=1; --i){
        while(last>0 && lcp[mys[last]] >= lcp[i]) --last;
        if(last==0) tr[i]=len+1; else tr[i]=mys[last];
        mys[++last]=i;
    }

    myset.clear();
    reset(dd,0);
    for(int i=1; i<=len; ++i){
        int bound = 0;
        if(lcp[i]==0){
            myset.clear();
            continue;
        }
        if(tl[i]>0) bound = max(bound, lcp[tl[i]]);
        if(tr[i]<=len) bound = max(bound, lcp[tr[i]]);
        int xlen = lcp[i];

        while(1){
            set<int>::iterator it;
            it=myset.lower_bound(xlen+1);
            if(it==myset.end()) break;
            myset.erase(it);
        }
        if(myset.find(xlen)!=myset.end()) continue;
        myset.insert(xlen);

        ll val=1;
        for(int j=0; j<3; ++j) val=val*(sum[j][tr[i]-1]-sum[j][tl[i]-1])%oo;
        dd[xlen]=(dd[xlen]+val)%oo;
        dd[bound]=(dd[bound]-val+oo)%oo;
    }



    int xlen=min(min(len1,len2),len3);
    ll val = 0;
    for(int i=xlen; i>=1; --i){
        val=(val+dd[i]+oo)%oo;
        res[i]=val;
    }
    for(int i=1; i<=xlen; ++i) printf("%I64d ",res[i]);
}
Example #24
0
pii get(int pos) {
    if (pos < 1 || pos > n) return pii(pos, pos);
    return prev(invhills.lower_bound(InvHill(pii(pos, INF), INF)))->first;
}
Example #25
0
int main()
{
	int n;
	scanf("%d",&n);
	for (int i = 1; i <= n; ++i)
	cir[i].read();
	
	
	//sort(cir+1,cir+n+1);
	for( int i = 1; i <= n; ++i)
	{
		e.push_back(make_pair(cir[i].x - cir[i].r, i));
		e.push_back(make_pair(cir[i].x + cir[i].r, -i));
	}
	sort(e.begin(),e.end());

	for (int i = 0; i < e.size(); ++i)
	{
		cur = e[i].first;
		if (e[i].second > 0){
			int id = e[i].second;
			set<circmp>::iterator t = s.lower_bound(circmp(id));
			if(t == s.end())
			{
				fa[id] = 0;
				son[0].push_back(id);
			}else{		
				int nid = (*t).id;
				if (nid > 0){
					fa[id] = nid;
					son[nid].push_back(id);
				}else{
					fa[id] = fa[-nid];
					son[fa[id]].push_back(id);
				}
			}
			s.insert(circmp(id));
			s.insert(circmp(-id));
		}else{
			int id = -e[i].second;
			s.erase(circmp(id));
			s.erase(circmp(-id));
		}
	}
//	memset(maxx,-1,sizeof(maxx));
	
//	dfs(0);
	
	int rear = -1,front = 0;
	q[++rear] = 0;
	while(front <= rear)
	{
		int x = q[front++];
	//	cout<<x<<endl;
		for (int i = 0; i < son[x].size(); ++i)
		{
			q[++rear] = son[x][i];
		}
	}
	for (int i = rear; i >= 0; --i)
		work(q[i]);
	
	cout<<maxx[0]<<endl;
	
	
	
	
	return 0;
}
int_t sparse_multivariate_distribution::get_rand_index(std::mt19937& _engine)
{
  rnd = uniform_01(_engine);
  it = cumulative.lower_bound(make_pair(rnd,0));
  return it->second;
}
Example #27
0
int main()
{
#ifndef ONLINE_JUDGE
    freopen("vd.inp","r",stdin);
    freopen("vd.out","w",stdout);
#endif
    scanf("%d%d%d%d%d%d",&m,&n,&t,&tp,&tu,&td);
    int i,j,u,kq=-1;
    set<int>::iterator it;
    int kqi,kqj,kqu,kqv,tg;
    for(i=1; i<=m; ++i)
    {
        for(j=1; j<=n; ++j) scanf("%d",&a[i][j]);
    }
    for(i=1; i<m; ++i)
    {
        for(u=i+1; u<=m; ++u)
        {
            for(j=1; j<=n; ++j) f[i][u][j]=f[i][u-1][j]+g(u-1,j,u,j);
        }
    }
    for(i=m; i>1; --i)
    {
        for(u=i-1; u>=1; --u)
        {
            for(j=1; j<=n; ++j) f[i][u][j]=f[i][u+1][j]+g(u+1,j,u,j);
        }
    }
    for(i=1; i+2<=m; ++i)
    {
        for(u=i+2; u<=m; ++u)
        {
            mm.clear();
            ms.clear();
            h[1]=-f[u][i][1];
            ms.insert(h[1]);
            mm[h[1]]=1;
            h[2]=-f[u][i][2]+g(i,1,i,2)+g(u,2,u,1);
            tg=g(i,1,i,2)+g(u,2,u,1);
            for(j=3; j<=n; ++j)
            {
                tg+=g(i,j-1,i,j)+g(u,j,u,j-1);
                it=ms.lower_bound(tg+f[i][u][j]-t);
                if (it!=ms.end())
                {
                    if (kq==-1 || abs(tg+f[i][u][j]-*it-t)<abs(kq-t))
                    {
                        kq=tg+f[i][u][j]-*it;
                        kqi=i;
                        kqj=mm[*it];
                        kqu=u;
                        kqv=j;
                    }
                }
                if (it!=ms.begin())
                {
                    it--;
                    if (kq==-1 || abs(tg+f[i][u][j]-*it-t)<abs(kq-t))
                    {
                        kq=tg+f[i][u][j]-*it;
                        kqi=i;
                        kqj=mm[*it];
                        kqu=u;
                        kqv=j;
                    }
                }
                h[j]=tg-f[u][i][j];
                ms.insert(h[j-1]);
                mm[h[j-1]]=j-1;
            }
        }
    }
    printf("%d %d %d %d",kqi,kqj,kqu,kqv);
}